diff options
author | Monty <monty@mariadb.org> | 2017-01-27 16:46:26 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2017-01-27 16:46:26 +0200 |
commit | 5c9baf54e7af994391aa0510f666b364ff2e657b (patch) | |
tree | b85b9f0cf42ab6eb3e11f1963f542e90925365a4 /mysys/my_thr_init.c | |
parent | 46eef1ede2ddfceaa056a71ea52ecacdde2bc44e (diff) | |
download | mariadb-git-5c9baf54e7af994391aa0510f666b364ff2e657b.tar.gz |
Fix for memory leak in applications, like QT,that calls
my_thread_global_init() + my_thrad_global_end() repeatadily.
This caused THR_KEY_mysys to be allocated multiple times.
Deletion of THR_KEY_mysys was originally in my_thread_global_end() but was
moved to my_end() as DBUG uses THR_KEY_mysys and DBUG is released after
my_thread_global_end() is called.
Releasing DBUG before my_thread_global_end() and move THR_KEY_mysys back
into my_thread_global_end() could be a solution, but as safe_mutex and other
things called by my_thread_global_end is using DBUG it may not be completely
safe.
To solve this, I used the simple solution to add a marker that THR_KEY_mysys
is created and not re-create it in my_thread_global_init if it already
exists.
Diffstat (limited to 'mysys/my_thr_init.c')
-rw-r--r-- | mysys/my_thr_init.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 3e4d091944b..aefd3564185 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -60,6 +60,8 @@ static uint get_thread_lib(void); /** True if @c my_thread_global_init() has been called. */ static my_bool my_thread_global_init_done= 0; +/* True if THR_KEY_mysys is created */ +my_bool my_thr_key_mysys_exists= 0; /* @@ -185,11 +187,20 @@ my_bool my_thread_global_init(void) return 0; my_thread_global_init_done= 1; - if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0) + /* + THR_KEY_mysys is deleted in my_end() as DBUG libraries are using it even + after my_thread_global_end() is called. + my_thr_key_mysys_exist is used to protect against application like QT + that calls my_thread_global_init() + my_thread_global_end() multiple times + without calling my_init() + my_end(). + */ + if (!my_thr_key_mysys_exists && + (pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0) { fprintf(stderr, "Can't initialize threads: error %d\n", pth_ret); return 1; } + my_thr_key_mysys_exists= 1; /* Mutex used by my_thread_init() and after my_thread_destroy_mutex() */ my_thread_init_internal_mutex(); |