Kluge solution for bug #566547: revert upstream's bad fix for their bug #45058. diff -Naur mysql-5.1.44.orig/include/my_sys.h mysql-5.1.44/include/my_sys.h --- mysql-5.1.44.orig/include/my_sys.h 2010-02-04 06:37:06.000000000 -0500 +++ mysql-5.1.44/include/my_sys.h 2010-02-19 23:13:48.000000000 -0500 @@ -951,6 +951,7 @@ 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); diff -Naur mysql-5.1.44.orig/libmysql/libmysql.c mysql-5.1.44/libmysql/libmysql.c --- mysql-5.1.44.orig/libmysql/libmysql.c 2010-02-04 06:37:07.000000000 -0500 +++ mysql-5.1.44/libmysql/libmysql.c 2010-02-19 23:13:48.000000000 -0500 @@ -211,6 +211,7 @@ } else { + free_charsets(); mysql_thread_end(); } diff -Naur mysql-5.1.44.orig/mysys/charset.c mysql-5.1.44/mysys/charset.c --- mysql-5.1.44.orig/mysys/charset.c 2010-02-04 06:38:50.000000000 -0500 +++ mysql-5.1.44/mysys/charset.c 2010-02-19 23:13:48.000000000 -0500 @@ -322,6 +321,7 @@ #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) @@ -399,37 +399,63 @@ } -static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT; - -static void init_available_charsets(void) +#ifdef __NETWARE__ +my_bool STDCALL init_available_charsets(myf myflags) +#else +static my_bool init_available_charsets(myf myflags) +#endif { char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; - 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++) + my_bool error=FALSE; + /* + We have to use charset_initialized to not lock on THR_LOCK_charset + inside get_internal_charset... + */ + if (!charset_initialized) { - if (*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[0]->ctype) - if (init_state_maps(*cs)) - *cs= NULL; + bzero(&all_charsets,sizeof(all_charsets)); + init_compiled_charsets(myflags); + + /* Copy compiled charsets */ + for (cs=all_charsets; + cs < all_charsets+array_elements(all_charsets)-1 ; + 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; } + pthread_mutex_unlock(&THR_LOCK_charset); } - - strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); - my_read_charset_file(fname, MYF(0)); + return error; +} + + +void free_charsets(void) +{ + charset_initialized=0; } uint get_collation_number(const char *name) { - my_pthread_once(&charsets_initialized, init_available_charsets); + init_available_charsets(MYF(0)); return get_collation_number_internal(name); } @@ -437,7 +463,7 @@ uint get_charset_number(const char *charset_name, uint cs_flags) { CHARSET_INFO **cs; - my_pthread_once(&charsets_initialized, init_available_charsets); + init_available_charsets(MYF(0)); for (cs= all_charsets; cs < all_charsets+array_elements(all_charsets)-1 ; @@ -454,7 +480,7 @@ const char *get_charset_name(uint charset_number) { CHARSET_INFO *cs; - my_pthread_once(&charsets_initialized, init_available_charsets); + init_available_charsets(MYF(0)); cs=all_charsets[charset_number]; if (cs && (cs->number == charset_number) && cs->name ) @@ -512,7 +538,7 @@ if (cs_number == default_charset_info->number) return default_charset_info; - my_pthread_once(&charsets_initialized, init_available_charsets); + (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ if (!cs_number || cs_number >= array_elements(all_charsets)-1) return NULL; @@ -534,7 +560,7 @@ { uint cs_number; CHARSET_INFO *cs; - my_pthread_once(&charsets_initialized, init_available_charsets); + (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ cs_number=get_collation_number(cs_name); cs= cs_number ? get_internal_charset(cs_number,flags) : NULL; @@ -559,7 +585,7 @@ DBUG_ENTER("get_charset_by_csname"); DBUG_PRINT("enter",("name: '%s'", cs_name)); - my_pthread_once(&charsets_initialized, init_available_charsets); + (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ cs_number= get_charset_number(cs_name, cs_flags); cs= cs_number ? get_internal_charset(cs_number, flags) : NULL; diff -Naur mysql-5.1.44.orig/mysys/my_init.c mysql-5.1.44/mysys/my_init.c --- mysql-5.1.44.orig/mysys/my_init.c 2010-02-04 06:38:51.000000000 -0500 +++ mysql-5.1.44/mysys/my_init.c 2010-02-19 23:13:48.000000000 -0500 @@ -165,6 +165,7 @@ my_print_open_files(); } } + free_charsets(); my_error_unregister_all(); my_once_free(); diff -Naur mysql-5.1.44.orig/netware/libmysqlmain.c mysql-5.1.44/netware/libmysqlmain.c --- mysql-5.1.44.orig/netware/libmysqlmain.c 2010-02-04 06:38:51.000000000 -0500 +++ mysql-5.1.44/netware/libmysqlmain.c 2010-02-19 23:13:48.000000000 -0500 @@ -18,7 +18,7 @@ #include "my_global.h" -void init_available_charsets(void); +my_bool init_available_charsets(myf myflags); /* this function is required so that global memory is allocated against this library nlm, and not against a paticular client */ @@ -31,7 +31,7 @@ { mysql_server_init(0, NULL, NULL); - init_available_charsets(); + init_available_charsets(MYF(0)); return 0; } diff -Naur mysql-5.1.44.orig/sql/mysqld.cc mysql-5.1.44/sql/mysqld.cc --- mysql-5.1.44.orig/sql/mysqld.cc 2010-02-04 06:39:50.000000000 -0500 +++ mysql-5.1.44/sql/mysqld.cc 2010-02-19 23:13:48.000000000 -0500 @@ -1287,6 +1287,7 @@ lex_free(); /* Free some memory */ item_create_cleanup(); set_var_free(); + free_charsets(); if (!opt_noacl) { #ifdef HAVE_DLOPEN