summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@montyprogram.com>2011-12-02 15:35:05 +0100
committerVladislav Vaintroub <wlad@montyprogram.com>2011-12-02 15:35:05 +0100
commitc4f5908a799e0b6ddcdc44f9957b5f99aaf40fd6 (patch)
tree8945418a6db73395e8a8136b49084d553dda51e9
parent970bc8cd0bd01073899a3f371cbe1ad3d0cf2057 (diff)
downloadmariadb-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.c22
-rw-r--r--mysys/my_thr_init.c15
-rw-r--r--storage/perfschema/pfs_atomic.cc5
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]);
}