diff options
author | Vladislav Vaintroub <wlad@montyprogram.com> | 2011-12-02 15:35:05 +0100 |
---|---|---|
committer | Vladislav Vaintroub <wlad@montyprogram.com> | 2011-12-02 15:35:05 +0100 |
commit | c4f5908a799e0b6ddcdc44f9957b5f99aaf40fd6 (patch) | |
tree | 8945418a6db73395e8a8136b49084d553dda51e9 | |
parent | 970bc8cd0bd01073899a3f371cbe1ad3d0cf2057 (diff) | |
download | mariadb-git-c4f5908a799e0b6ddcdc44f9957b5f99aaf40fd6.tar.gz |
Fixed crashes found by application verifier:
- leaking mutex in lf_hash_destroy
- pthread_getspecific() before pthread_key_create() in my_thread_var_dbug()
(called by static C++ object constructors called in sys_vars)
- perfschema destroys mutexes that were not created.
-rw-r--r-- | mysys/lf_hash.c | 22 | ||||
-rw-r--r-- | mysys/my_thr_init.c | 15 | ||||
-rw-r--r-- | storage/perfschema/pfs_atomic.cc | 5 |
3 files changed, 24 insertions, 18 deletions
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index 28e97192f18..83cfe1a1639 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -335,18 +335,18 @@ void lf_hash_destroy(LF_HASH *hash) { LF_SLIST *el, **head= (LF_SLIST **)_lf_dynarray_value(&hash->array, 0); - if (unlikely(!head)) - return; - el= *head; - - while (el) + if (head) { - intptr next= el->link; - if (el->hashnr & 1) - lf_alloc_direct_free(&hash->alloc, el); /* normal node */ - else - my_free(el); /* dummy node */ - el= (LF_SLIST *)next; + el= *head; + while (el) + { + intptr next= el->link; + if (el->hashnr & 1) + lf_alloc_direct_free(&hash->alloc, el); /* normal node */ + else + my_free(el); /* dummy node */ + el= (LF_SLIST *)next; + } } lf_alloc_destroy(&hash->alloc); lf_dynarray_destroy(&hash->array); diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index e2e03cc37a8..a2d34225e32 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -228,7 +228,6 @@ void my_thread_global_end(void) } mysql_mutex_unlock(&THR_LOCK_threads); - pthread_key_delete(THR_KEY_mysys); mysql_mutex_destroy(&THR_LOCK_malloc); mysql_mutex_destroy(&THR_LOCK_open); mysql_mutex_destroy(&THR_LOCK_lock); @@ -246,7 +245,7 @@ void my_thread_global_end(void) #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) mysql_mutex_destroy(&LOCK_localtime_r); #endif - + pthread_key_delete(THR_KEY_mysys); my_thread_global_init_done= 0; } @@ -429,8 +428,10 @@ const char *my_thread_name(void) extern void **my_thread_var_dbug() { - struct st_my_thread_var *tmp= - my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); + struct st_my_thread_var *tmp; + if (!my_thread_global_init_done) + return NULL; + tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); return tmp && tmp->init ? &tmp->dbug : 0; } #endif /* DBUG_OFF */ @@ -439,8 +440,10 @@ extern void **my_thread_var_dbug() 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); + struct st_my_thread_var *tmp; + if (!my_thread_global_init_done) + return NULL; + tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); return tmp ? &tmp->mutex_in_use : 0; } diff --git a/storage/perfschema/pfs_atomic.cc b/storage/perfschema/pfs_atomic.cc index 3bd744c8ea7..4db807b1d88 100644 --- a/storage/perfschema/pfs_atomic.cc +++ b/storage/perfschema/pfs_atomic.cc @@ -61,6 +61,7 @@ operation. */ my_atomic_rwlock_t PFS_atomic::m_rwlock_array[256]; +static int init_done; void PFS_atomic::init(void) { @@ -68,12 +69,14 @@ void PFS_atomic::init(void) for (i=0; i< array_elements(m_rwlock_array); i++) my_atomic_rwlock_init(&m_rwlock_array[i]); + init_done= 1; } void PFS_atomic::cleanup(void) { uint i; - + if (!init_done) + return; for (i=0; i< array_elements(m_rwlock_array); i++) my_atomic_rwlock_destroy(&m_rwlock_array[i]); } |