diff options
author | Staale Smedseng <staale.smedseng@sun.com> | 2009-12-12 19:11:25 +0100 |
---|---|---|
committer | Staale Smedseng <staale.smedseng@sun.com> | 2009-12-12 19:11:25 +0100 |
commit | 8969530cffde0c7a466cf3aa8c4b7462d0ace2d2 (patch) | |
tree | e11d1534328b91e686c5a4590990a39cf3e6eeb6 /include | |
parent | 0654e74a708247a461953726b3f4d3e18b78b6d4 (diff) | |
download | mariadb-git-8969530cffde0c7a466cf3aa8c4b7462d0ace2d2.tar.gz |
Bug #45058 init_available_charsets uses double checked locking
As documented in the bug report, the double checked locking
pattern has inherent issues, and cannot guarantee correct
initialization.
This patch replaces the logic in init_available_charsets()
with the use of pthread_once(3). A wrapper function,
my_pthread_once(), is introduced and is used in lieu of direct
calls to init_available_charsets(). Related defines
MY_PTHREAD_ONCE_* are also introduced.
For the Windows platform, the implementation in lp:sysbench is
ported. For single-thread use, a simple define calls the
function and sets the pthread_once control variable.
Charset initialization is modified to use my_pthread_once().
include/my_no_pthread.h:
Dummy my_pthread_once() for single thread use.
include/my_pthread.h:
Declaration for new function my_pthread_once().
mysys/charset.c:
Logic in init_available_charsets() is simplified.
Using my_pthread_once() for all calls to this func.
mysys/my_winthread.c:
Windows implementation of my_pthread_once().
Diffstat (limited to 'include')
-rw-r--r-- | include/my_no_pthread.h | 8 | ||||
-rw-r--r-- | include/my_pthread.h | 10 | ||||
-rw-r--r-- | include/my_sys.h | 1 |
3 files changed, 18 insertions, 1 deletions
diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h index b11dbff42f0..511fac407d5 100644 --- a/include/my_no_pthread.h +++ b/include/my_no_pthread.h @@ -47,4 +47,12 @@ #define rw_unlock(A) #define rwlock_destroy(A) +typedef int my_pthread_once_t; +#define MY_PTHREAD_ONCE_INIT 0 +#define MY_PTHREAD_ONCE_DONE 1 + +#define my_pthread_once(C,F) do { \ + if (*(C) != MY_PTHREAD_ONCE_DONE) { F(); *(C)= MY_PTHREAD_ONCE_DONE; } \ + } while(0) + #endif diff --git a/include/my_pthread.h b/include/my_pthread.h index 151cb34faff..e9256610ea7 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -69,6 +69,11 @@ typedef int pthread_mutexattr_t; #define pthread_handler_t EXTERNC void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); +typedef volatile LONG my_pthread_once_t; +#define MY_PTHREAD_ONCE_INIT 0 +#define MY_PTHREAD_ONCE_INPROGRESS 1 +#define MY_PTHREAD_ONCE_DONE 2 + /* Struct and macros to be used in combination with the windows implementation of pthread_cond_timedwait @@ -114,6 +119,7 @@ int pthread_attr_init(pthread_attr_t *connect_att); int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); int pthread_attr_destroy(pthread_attr_t *connect_att); +int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void)); struct tm *localtime_r(const time_t *timep,struct tm *tmp); struct tm *gmtime_r(const time_t *timep,struct tm *tmp); @@ -210,6 +216,10 @@ extern int my_pthread_getprio(pthread_t thread_id); #define pthread_handler_t EXTERNC void * typedef void *(* pthread_handler)(void *); +#define my_pthread_once_t pthread_once_t +#define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT +#define my_pthread_once(C,F) pthread_once(C,F) + /* Test first for RTS or FSU threads */ #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) diff --git a/include/my_sys.h b/include/my_sys.h index b4aac3a17bd..a4ff5c30de7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -951,7 +951,6 @@ extern my_bool resolve_collation(const char *cl_name, CHARSET_INFO *default_cl, CHARSET_INFO **cl); -extern void free_charsets(void); extern char *get_charsets_dir(char *buf); extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2); extern my_bool init_compiled_charsets(myf flags); |