enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_INFO *owner, ulong lock_wait_timeout) { THR_LOCK_DATA **pos,**end; DBUG_ENTER("thr_multi_lock"); DBUG_PRINT("lock",("data: 0x%lx count: %d", (long) data, count)); if (count > 1) sort_locks(data,count); /* lock everything */ for (pos=data,end=data+count; pos < end ; pos++) { enum enum_thr_lock_result result= thr_lock(*pos, owner, (*pos)->type, lock_wait_timeout); if (result != THR_LOCK_SUCCESS) { /* Aborted */ thr_multi_unlock(data,(uint) (pos-data)); DBUG_RETURN(result); } DEBUG_SYNC_C("thr_multi_lock_after_thr_lock"); #ifdef MAIN printf("Thread: %s Got lock: 0x%lx type: %d\n",my_thread_name(), (long) pos[0]->lock, pos[0]->type); fflush(stdout); #endif } thr_lock_merge_status(data, count); DBUG_RETURN(THR_LOCK_SUCCESS); }
my_bool my_thread_init(void) { struct st_my_thread_var *tmp; my_bool error=0; if (!my_thread_global_init_done) return 1; /* cannot proceed with unintialized library */ #ifdef EXTRA_DEBUG_THREADS my_message_local(INFORMATION_LEVEL, "my_thread_init(): thread_id: 0x%lx", (ulong) pthread_self()); #endif if (_my_thread_var()) { #ifdef EXTRA_DEBUG_THREADS my_message_local(WARNING_LEVEL, "my_thread_init() called more than once in thread 0x%lx", (long) pthread_self()); #endif goto end; } #ifdef _MSC_VER install_sigabrt_handler(); #endif if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp)))) { error= 1; goto end; } set_mysys_var(tmp); tmp->pthread_self= pthread_self(); mysql_mutex_init(key_my_thread_var_mutex, &tmp->mutex, MY_MUTEX_INIT_FAST); mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL); tmp->stack_ends_here= (char*)&tmp + STACK_DIRECTION * (long)my_thread_stack_size; mysql_mutex_lock(&THR_LOCK_threads); tmp->id= ++thread_id; ++THR_thread_count; mysql_mutex_unlock(&THR_LOCK_threads); tmp->init= 1; #ifndef DBUG_OFF /* Generate unique name for thread */ (void) my_thread_name(); #endif end: return error; }
static void *test_thread_writer(void *arg) { int param=*((int*) arg); my_thread_init(); { DBUG_ENTER_NO_RETURN("test_writer"); writer(param); DBUG_PRINT("info", ("Thread %s ended", my_thread_name())); pthread_mutex_lock(&LOCK_thread_count); ok(1, "writer%d: done", param); thread_count--; pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */ pthread_mutex_unlock(&LOCK_thread_count); free((uchar*) arg); my_thread_end(); } return 0; }
void thr_multi_unlock(THR_LOCK_DATA **data,uint count) { THR_LOCK_DATA **pos,**end; DBUG_ENTER("thr_multi_unlock"); DBUG_PRINT("lock",("data: %lx count: %d",data,count)); for (pos=data,end=data+count; pos < end ; pos++) { #ifdef MAIN printf("Thread: %s Rel lock: %lx type: %d\n", my_thread_name(), (long) pos[0]->lock, pos[0]->type); fflush(stdout); #endif if ((*pos)->type != TL_UNLOCK) thr_unlock(*pos); else { DBUG_PRINT("lock",("Free lock: data: %lx thread: %ld lock: %lx", *pos,(*pos)->thread_id,(*pos)->lock)); } } DBUG_VOID_RETURN; }
enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner) { THR_LOCK_DATA **pos,**end; DBUG_ENTER("thr_multi_lock"); DBUG_PRINT("lock",("data: 0x%lx count: %d", (long) data, count)); if (count > 1) sort_locks(data,count); /* lock everything */ for (pos=data,end=data+count; pos < end ; pos++) { enum enum_thr_lock_result result= thr_lock(*pos, owner, (*pos)->type); if (result != THR_LOCK_SUCCESS) { /* Aborted */ thr_multi_unlock(data,(uint) (pos-data)); DBUG_RETURN(result); } #ifdef MAIN printf("Thread: %s Got lock: 0x%lx type: %d\n",my_thread_name(), (long) pos[0]->lock, pos[0]->type); fflush(stdout); #endif } /* Ensure that all get_locks() have the same status If we lock the same table multiple times, we must use the same status_param! */ #if !defined(DONT_USE_RW_LOCKS) if (count > 1) { THR_LOCK_DATA *last_lock= end[-1]; pos=end-1; do { pos--; if (last_lock->lock == (*pos)->lock && last_lock->lock->copy_status) { if (last_lock->type <= TL_READ_NO_INSERT) { THR_LOCK_DATA **read_lock; /* If we are locking the same table with read locks we must ensure that all tables share the status of the last write lock or the same read lock. */ for (; (*pos)->type <= TL_READ_NO_INSERT && pos != data && pos[-1]->lock == (*pos)->lock ; pos--) ; read_lock = pos+1; do { (last_lock->lock->copy_status)((*read_lock)->status_param, (*pos)->status_param); } while (*(read_lock++) != last_lock); last_lock= (*pos); /* Point at last write lock */ } else (*last_lock->lock->copy_status)((*pos)->status_param, last_lock->status_param); } else last_lock=(*pos); } while (pos != data); } #endif DBUG_RETURN(THR_LOCK_SUCCESS); }