diff options
Diffstat (limited to 'mysys/my_thr_init.c')
-rw-r--r-- | mysys/my_thr_init.c | 121 |
1 files changed, 89 insertions, 32 deletions
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 1d03577ce34..6ebd1f512f1 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -115,6 +115,15 @@ my_bool my_thread_global_init(void) } #endif /* TARGET_OS_LINUX */ + /* Mutex used by my_thread_init() and after my_thread_destroy_mutex() */ + my_pthread_mutex_init(&THR_LOCK_threads, MY_MUTEX_INIT_FAST, + "THR_LOCK_threads", MYF_NO_DEADLOCK_DETECTION); + my_pthread_mutex_init(&THR_LOCK_malloc, MY_MUTEX_INIT_FAST, + "THR_LOCK_malloc", MYF_NO_DEADLOCK_DETECTION); + + if (my_thread_init()) + return 1; + #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP /* Set mutex type to "fast" a.k.a "adaptive" @@ -138,7 +147,7 @@ my_bool my_thread_global_init(void) PTHREAD_MUTEX_ERRORCHECK); #endif - pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST); + /* Mutex uses by mysys */ pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW); @@ -146,7 +155,6 @@ my_bool my_thread_global_init(void) pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST); pthread_cond_init(&THR_COND_threads, NULL); #if defined( __WIN__) || defined(OS2) @@ -158,44 +166,64 @@ my_bool my_thread_global_init(void) #ifndef HAVE_GETHOSTBYNAME_R pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW); #endif - if (my_thread_init()) - { - my_thread_global_end(); /* Clean up */ - return 1; - } return 0; } -void my_thread_global_end(void) +/** + Wait for all threads in system to die + @fn my_wait_for_other_threads_to_die() + @param number_of_threads Wait until this number of threads + + @retval 0 Less or equal to number_of_threads left + @retval 1 Wait failed +*/ + +my_bool my_wait_for_other_threads_to_die(uint number_of_threads) { struct timespec abstime; my_bool all_threads_killed= 1; set_timespec(abstime, my_thread_end_wait_time); pthread_mutex_lock(&THR_LOCK_threads); - while (THR_thread_count > 0) + while (THR_thread_count > number_of_threads) { int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads, &abstime); if (error == ETIMEDOUT || error == ETIME) { -#ifdef HAVE_PTHREAD_KILL - /* - We shouldn't give an error here, because if we don't have - pthread_kill(), programs like mysqld can't ensure that all threads - are killed when we enter here. - */ - if (THR_thread_count) - fprintf(stderr, - "Error in my_thread_global_end(): %d threads didn't exit\n", - THR_thread_count); -#endif all_threads_killed= 0; break; } } pthread_mutex_unlock(&THR_LOCK_threads); + return all_threads_killed; +} + + +/** + End the mysys thread system. Called when ending the last thread +*/ + + +void my_thread_global_end(void) +{ + my_bool all_threads_killed; + + if (!(all_threads_killed= my_wait_for_other_threads_to_die(0))) + { +#ifdef HAVE_PTHREAD_KILL + /* + We shouldn't give an error here, because if we don't have + pthread_kill(), programs like mysqld can't ensure that all threads + are killed when we enter here. + */ + if (THR_thread_count) + fprintf(stderr, + "Error in my_thread_global_end(): %d threads didn't exit\n", + THR_thread_count); +#endif + } pthread_key_delete(THR_KEY_mysys); #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP @@ -204,7 +232,25 @@ void my_thread_global_end(void) #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_errorcheck_mutexattr); #endif - pthread_mutex_destroy(&THR_LOCK_malloc); + if (all_threads_killed) + { + pthread_mutex_destroy(&THR_LOCK_threads); + pthread_cond_destroy(&THR_COND_threads); + pthread_mutex_destroy(&THR_LOCK_malloc); + } +} + +/* Free all mutex used by mysys */ + +void my_thread_destroy_mutex(void) +{ + struct st_my_thread_var *tmp; + tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); + if (tmp) + { + safe_mutex_free_deadlock_data(&tmp->mutex); + } + pthread_mutex_destroy(&THR_LOCK_open); pthread_mutex_destroy(&THR_LOCK_lock); pthread_mutex_destroy(&THR_LOCK_isam); @@ -213,11 +259,6 @@ void my_thread_global_end(void) pthread_mutex_destroy(&THR_LOCK_net); pthread_mutex_destroy(&THR_LOCK_time); pthread_mutex_destroy(&THR_LOCK_charset); - if (all_threads_killed) - { - pthread_mutex_destroy(&THR_LOCK_threads); - pthread_cond_destroy(&THR_COND_threads); - } #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) pthread_mutex_destroy(&LOCK_localtime_r); #endif @@ -287,7 +328,8 @@ my_bool my_thread_init(void) #else tmp->pthread_self= pthread_self(); #endif - pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST); + my_pthread_mutex_init(&tmp->mutex, MY_MUTEX_INIT_FAST, "mysys_var->mutex", + 0); pthread_cond_init(&tmp->suspend, NULL); tmp->stack_ends_here= &tmp + STACK_DIRECTION * my_thread_stack_size; @@ -330,6 +372,13 @@ void my_thread_end(void) #endif if (tmp && tmp->init) { + +#if !defined(__bsdi__) && !defined(__OpenBSD__) + /* bsdi and openbsd 3.5 dumps core here */ + pthread_cond_destroy(&tmp->suspend); +#endif + pthread_mutex_destroy(&tmp->mutex); + #if !defined(DBUG_OFF) /* tmp->dbug is allocated inside DBUG library */ if (tmp->dbug) @@ -339,12 +388,11 @@ void my_thread_end(void) tmp->dbug=0; } #endif -#if !defined(__bsdi__) && !defined(__OpenBSD__) - /* bsdi and openbsd 3.5 dumps core here */ - pthread_cond_destroy(&tmp->suspend); -#endif - pthread_mutex_destroy(&tmp->mutex); #if !defined(__WIN__) || defined(USE_TLS) +#ifndef DBUG_OFF + /* To find bugs when accessing unallocated data */ + bfill(tmp, sizeof(tmp), 0x8F); +#endif free(tmp); #else tmp->init= 0; @@ -399,6 +447,15 @@ extern void **my_thread_var_dbug() } #endif +/* Return pointer to mutex_in_use */ + +safe_mutex_t **my_thread_var_mutex_in_use() +{ + struct st_my_thread_var *tmp= + my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); + return tmp ? &tmp->mutex_in_use : 0; +} + /**************************************************************************** Get name of current thread. ****************************************************************************/ |