summaryrefslogtreecommitdiff
path: root/mysys/my_thr_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/my_thr_init.c')
-rw-r--r--mysys/my_thr_init.c121
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.
****************************************************************************/