diff options
Diffstat (limited to 'mysys/thr_lock.c')
-rw-r--r-- | mysys/thr_lock.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 7c92a7fa5fa..7d86d0c9524 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -85,6 +85,7 @@ multiple read locks. my_bool thr_lock_inited=0; ulong locks_immediate = 0L, locks_waited = 0L; +enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE; /* The following constants are only for debug output */ #define MAX_THREADS 100 @@ -110,7 +111,8 @@ my_bool init_thr_lock() } #ifdef EXTRA_DEBUG -static int found_errors=0; +#define MAX_FOUND_ERRORS 10 /* Report 10 first errors */ +static uint found_errors=0; static int check_lock(struct st_lock_list *list, const char* lock_type, const char *where, my_bool same_thread) @@ -167,15 +169,16 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, static void check_locks(THR_LOCK *lock, const char *where, my_bool allow_no_locks) { - if (!found_errors) + uint old_found_errors=found_errors; + if (found_errors < MAX_FOUND_ERRORS) { if (check_lock(&lock->write,"write",where,1) | check_lock(&lock->write_wait,"write_wait",where,0) | check_lock(&lock->read,"read",where,0) | check_lock(&lock->read_wait,"read_wait",where,0)) - found_errors=1; + found_errors++; - if (!found_errors) + if (found_errors < MAX_FOUND_ERRORS) { uint count=0; THR_LOCK_DATA *data; @@ -186,7 +189,7 @@ static void check_locks(THR_LOCK *lock, const char *where, } if (count != lock->read_no_write_count) { - found_errors=1; + found_errors++; fprintf(stderr, "Warning at '%s': Locks read_no_write_count was %u when it should have been %u\n", where, lock->read_no_write_count,count); } @@ -196,7 +199,7 @@ static void check_locks(THR_LOCK *lock, const char *where, if (!allow_no_locks && !lock->read.data && (lock->write_wait.data || lock->read_wait.data)) { - found_errors=1; + found_errors++; fprintf(stderr, "Warning at '%s': No locks in use but locks are in wait queue\n", where); @@ -205,7 +208,7 @@ static void check_locks(THR_LOCK *lock, const char *where, { if (!allow_no_locks && lock->read_wait.data) { - found_errors=1; + found_errors++; fprintf(stderr, "Warning at '%s': No write locks and waiting read locks\n", where); @@ -221,7 +224,7 @@ static void check_locks(THR_LOCK *lock, const char *where, (lock->write_wait.data->type == TL_WRITE_DELAYED && !lock->read.data))) { - found_errors=1; + found_errors++; fprintf(stderr, "Warning at '%s': Write lock %d waiting while no exclusive read locks\n",where,(int) lock->write_wait.data->type); } @@ -235,7 +238,7 @@ static void check_locks(THR_LOCK *lock, const char *where, lock->write.data->type == TL_WRITE_ALLOW_WRITE && lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE) { - found_errors=1; + found_errors++; fprintf(stderr, "Warning at '%s': Found WRITE_ALLOW_WRITE lock waiting for WRITE_ALLOW_WRITE lock\n", where); @@ -243,16 +246,18 @@ static void check_locks(THR_LOCK *lock, const char *where, } if (lock->read.data) { - if ((!pthread_equal(lock->write.data->thread,lock->read.data->thread) && - lock->write.data->type > TL_WRITE_DELAYED) || + if ((!pthread_equal(lock->write.data->thread, + lock->read.data->thread) && + lock->write.data->type > TL_WRITE_DELAYED && + lock->write.data->type != TL_WRITE_ONLY) || ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT || lock->write.data->type == TL_WRITE_ALLOW_WRITE) && lock->read_no_write_count)) { - found_errors=1; + found_errors++; fprintf(stderr, - "Warning at '%s': Found lock that is write and read locked\n", - where); + "Warning at '%s': Found lock of type %d that is write and read locked\n", + where, lock->write.data->type); } } if (lock->read_wait.data) @@ -260,7 +265,7 @@ static void check_locks(THR_LOCK *lock, const char *where, if (!allow_no_locks && lock->write.data->type <= TL_WRITE_DELAYED && lock->read_wait.data->type <= TL_READ_HIGH_PRIORITY) { - found_errors=1; + found_errors++; fprintf(stderr, "Warning at '%s': Found read lock of type %d waiting for write lock of type %d\n", where, @@ -270,7 +275,7 @@ static void check_locks(THR_LOCK *lock, const char *where, } } } - if (found_errors) + if (found_errors != old_found_errors) { DBUG_PRINT("error",("Found wrong lock")); } @@ -510,7 +515,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type) } } else if (lock_type == TL_WRITE_CONCURRENT_INSERT && ! lock->check_status) - data->type=lock_type= TL_WRITE; /* not supported */ + data->type=lock_type= thr_upgraded_concurrent_insert_lock; if (lock->write.data) /* If there is a write lock */ { @@ -552,7 +557,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type) { /* no scheduled write locks */ if (lock_type == TL_WRITE_CONCURRENT_INSERT && (*lock->check_status)(data->status_param)) - data->type=lock_type=TL_WRITE; /* Upgrade lock */ + data->type=lock_type= thr_upgraded_concurrent_insert_lock; if (!lock->read.data || (lock_type <= TL_WRITE_DELAYED && @@ -939,10 +944,10 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data) DBUG_ENTER("thr_upgrade_write_delay_lock"); pthread_mutex_lock(&lock->mutex); - if (data->type == TL_UNLOCK || data->type == TL_WRITE) /* Aborted */ + if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY) { pthread_mutex_unlock(&lock->mutex); - DBUG_RETURN(data->type == TL_UNLOCK); + DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */ } check_locks(lock,"before upgrading lock",0); /* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */ |