diff options
author | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2009-12-16 16:47:07 +0300 |
---|---|---|
committer | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2009-12-16 16:47:07 +0300 |
commit | efe619585840b27ef156b35f2be6ef3c9809d2e5 (patch) | |
tree | fa68ffcd1dbdaf248e483a5692358fe7330ec507 /mysys | |
parent | a1218bb782f646111c9302740b4c443e3fed6d88 (diff) | |
parent | 8f32ccff6032e03782ad805b97328f2e5e047384 (diff) | |
download | mariadb-git-efe619585840b27ef156b35f2be6ef3c9809d2e5.tar.gz |
Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/charset.c | 80 | ||||
-rw-r--r-- | mysys/my_init.c | 1 | ||||
-rw-r--r-- | mysys/my_winthread.c | 32 |
3 files changed, 59 insertions, 54 deletions
diff --git a/mysys/charset.c b/mysys/charset.c index 280b2ad6091..cff7d014148 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -220,7 +220,8 @@ copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from) static int add_collation(CHARSET_INFO *cs) { if (cs->name && (cs->number || - (cs->number=get_collation_number_internal(cs->name)))) + (cs->number=get_collation_number_internal(cs->name))) && + cs->number < array_elements(all_charsets)) { if (!all_charsets[cs->number]) { @@ -324,7 +325,6 @@ static int add_collation(CHARSET_INFO *cs) #define MY_CHARSET_INDEX "Index.xml" const char *charsets_dir= NULL; -static int charset_initialized=0; static my_bool my_read_charset_file(const char *filename, myf myflags) @@ -402,63 +402,37 @@ static void *cs_alloc(size_t size) } -#ifdef __NETWARE__ -my_bool STDCALL init_available_charsets(myf myflags) -#else -static my_bool init_available_charsets(myf myflags) -#endif +static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT; + +static void init_available_charsets(void) { char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; - my_bool error=FALSE; - /* - We have to use charset_initialized to not lock on THR_LOCK_charset - inside get_internal_charset... - */ - if (!charset_initialized) + CHARSET_INFO **cs; + + bzero(&all_charsets,sizeof(all_charsets)); + init_compiled_charsets(MYF(0)); + + /* Copy compiled charsets */ + for (cs=all_charsets; + cs < all_charsets+array_elements(all_charsets)-1 ; + cs++) { - CHARSET_INFO **cs; - /* - To make things thread safe we are not allowing other threads to interfere - while we may changing the cs_info_table - */ - pthread_mutex_lock(&THR_LOCK_charset); - if (!charset_initialized) + if (*cs) { - bzero(&all_charsets,sizeof(all_charsets)); - init_compiled_charsets(myflags); - - /* Copy compiled charsets */ - for (cs=all_charsets; - cs < all_charsets + array_elements(all_charsets); - cs++) - { - if (*cs) - { - if (cs[0]->ctype) - if (init_state_maps(*cs)) - *cs= NULL; - } - } - - strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); - error= my_read_charset_file(fname,myflags); - charset_initialized=1; + if (cs[0]->ctype) + if (init_state_maps(*cs)) + *cs= NULL; } - pthread_mutex_unlock(&THR_LOCK_charset); } - return error; -} - - -void free_charsets(void) -{ - charset_initialized=0; + + strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); + my_read_charset_file(fname, MYF(0)); } uint get_collation_number(const char *name) { - init_available_charsets(MYF(0)); + my_pthread_once(&charsets_initialized, init_available_charsets); return get_collation_number_internal(name); } @@ -466,7 +440,7 @@ uint get_collation_number(const char *name) uint get_charset_number(const char *charset_name, uint cs_flags) { CHARSET_INFO **cs; - init_available_charsets(MYF(0)); + my_pthread_once(&charsets_initialized, init_available_charsets); for (cs= all_charsets; cs < all_charsets + array_elements(all_charsets); @@ -483,7 +457,7 @@ uint get_charset_number(const char *charset_name, uint cs_flags) const char *get_charset_name(uint charset_number) { CHARSET_INFO *cs; - init_available_charsets(MYF(0)); + my_pthread_once(&charsets_initialized, init_available_charsets); cs=all_charsets[charset_number]; if (cs && (cs->number == charset_number) && cs->name ) @@ -541,7 +515,7 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags) if (cs_number == default_charset_info->number) return default_charset_info; - (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ + my_pthread_once(&charsets_initialized, init_available_charsets); if (!cs_number || cs_number > array_elements(all_charsets)) return NULL; @@ -563,7 +537,7 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags) { uint cs_number; CHARSET_INFO *cs; - (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ + my_pthread_once(&charsets_initialized, init_available_charsets); cs_number=get_collation_number(cs_name); cs= cs_number ? get_internal_charset(cs_number,flags) : NULL; @@ -588,7 +562,7 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, DBUG_ENTER("get_charset_by_csname"); DBUG_PRINT("enter",("name: '%s'", cs_name)); - (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ + my_pthread_once(&charsets_initialized, init_available_charsets); cs_number= get_charset_number(cs_name, cs_flags); cs= cs_number ? get_internal_charset(cs_number, flags) : NULL; diff --git a/mysys/my_init.c b/mysys/my_init.c index c4fda599481..1dc51f065ae 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -167,7 +167,6 @@ void my_end(int infoflag) my_print_open_files(); } } - free_charsets(); my_error_unregister_all(); my_once_free(); diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c index 9e8458b0799..290351099a4 100644 --- a/mysys/my_winthread.c +++ b/mysys/my_winthread.c @@ -129,4 +129,36 @@ error_return: return -1; } + +/* + One time initialization. For simplicity, we assume initializer thread + does not exit within init_routine(). +*/ +int my_pthread_once(my_pthread_once_t *once_control, + void (*init_routine)(void)) +{ + LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS, + MY_PTHREAD_ONCE_INIT); + switch(state) + { + case MY_PTHREAD_ONCE_INIT: + /* This is initializer thread */ + (*init_routine)(); + *once_control= MY_PTHREAD_ONCE_DONE; + break; + + case MY_PTHREAD_ONCE_INPROGRESS: + /* init_routine in progress. Wait for its completion */ + while(*once_control == MY_PTHREAD_ONCE_INPROGRESS) + { + Sleep(1); + } + break; + case MY_PTHREAD_ONCE_DONE: + /* Nothing to do */ + break; + } + return 0; +} + #endif |