List:Commits« Previous MessageNext Message »
From:Staale Smedseng Date:September 11 2009 5:24pm
Subject:bzr commit into mysql-5.1-bugteam branch (staale.smedseng:3120) Bug#45058
View as plain text  
#At file:///export/home/tmp/ss156133/z/45058-51/ based on revid:alik@stripped

 3120 Staale Smedseng	2009-09-11
      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 modifies the charset initialization code to do its
      work during server/client initialization, and not through
      calls to get_charset_*(). This is achieved by splitting
      init_available_charsets() into two functions:
      
       * load_compiled_charsets(): loads the compiled character
         sets, called from my_init(),
       * load_available_charsets(): loads charset index file after
         any options regarding charset directory have been
         processed; called explicitly in mysqld.cc, mysqldump.cc
         a.o., and implicitly in clients through
         mysql_library_init().
      
      The split is necessary to support functions relying on
      charsets that are used early on, while giving the possibility
      of changing the source charsets_dir (e.g., during options
      parsing) before loading charset definitions.
     @ client/mysqldump.c
        Adding explicit loading of charset info from file.
     @ extra/charset2html.c
        Adding explicit loading of charset info from file.
     @ extra/comp_err.c
        Adding explicit loading of charset info from file.
     @ include/my_sys.h
        init_available_charsets() is split into two functions.
     @ libmysql/libmysql.c
        Adding explicit loading of charset info from file.
     @ mysys/charset.c
        init_available_charsets() is split into two functions. Calls
        to init_available_charsets() are dropped from the get_charset*() functions.
     @ mysys/my_init.c
        Adding explicit loading of compiled charsets in my_init().
     @ netware/libmysqlmain.c
        Charset loading now happens in my_init() and mysql_server_init().
     @ sql/mysqld.cc
        Adding explicit loading of charset info from file.

    modified:
      client/mysqldump.c
      extra/charset2html.c
      extra/comp_err.c
      include/my_sys.h
      libmysql/libmysql.c
      mysys/charset.c
      mysys/my_init.c
      netware/libmysqlmain.c
      sql/mysqld.cc
=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2009-08-28 15:06:59 +0000
+++ b/client/mysqldump.c	2009-09-11 17:24:20 +0000
@@ -921,6 +921,7 @@ static int get_options(int *argc, char *
             my_progname);
     return(EX_USAGE);
   }
+  load_available_charsets(MYF(0));
   if (strcmp(default_charset, charset_info->csname) &&
       !(charset_info= get_charset_by_csname(default_charset,
                                             MY_CS_PRIMARY, MYF(MY_WME))))

=== modified file 'extra/charset2html.c'
--- a/extra/charset2html.c	2008-03-29 14:15:06 +0000
+++ b/extra/charset2html.c	2009-09-11 17:24:20 +0000
@@ -120,8 +120,6 @@ static void print_index()
   CHARSET_INFO **cs;
   int clr=0; 
   
-  get_charset_by_name("",MYF(0));	/* To execute init_available_charsets */
-  
   printf("All charsets\n");
   printf("<table border=1>\n");
   printf("<tr bgcolor=EEEE99><th>ID<th>Charset<th>Collation<th>Def<th>Bin<th>Com<th>Comment\n");
@@ -162,7 +160,8 @@ int main(int argc, char **argv) {
 
   if (argc > argcnt)
     charsets_dir = argv[argcnt++];
-
+  load_available_charsets(MYF(0));
+  
   if (!the_set)
   {
     print_index();

=== modified file 'extra/comp_err.c'
--- a/extra/comp_err.c	2009-02-13 16:41:47 +0000
+++ b/extra/comp_err.c	2009-09-11 17:24:20 +0000
@@ -167,6 +167,7 @@ int main(int argc, char *argv[])
     DBUG_ENTER("main");
 
     charsets_dir= DEFAULT_CHARSET_DIR;
+    load_available_charsets(MYF(0));
     my_umask_dir= 0777;
     if (get_options(&argc, &argv))
       DBUG_RETURN(1);

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2009-09-03 12:29:25 +0000
+++ b/include/my_sys.h	2009-09-11 17:24:20 +0000
@@ -926,6 +926,8 @@ int my_getpagesize(void);
 int my_msync(int, void *, size_t, int);
 
 /* character sets */
+extern void load_compiled_charsets(myf myflags);
+extern my_bool load_available_charsets(myf myflags);
 extern uint get_charset_number(const char *cs_name, uint cs_flags);
 extern uint get_collation_number(const char *name);
 extern const char *get_charset_name(uint cs_number);

=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c	2009-08-28 16:21:54 +0000
+++ b/libmysql/libmysql.c	2009-09-11 17:24:20 +0000
@@ -125,6 +125,7 @@ int STDCALL mysql_server_init(int argc _
     org_my_init_done=my_init_done;
     if (my_init())				/* Will init threads */
       return 1;
+    load_available_charsets(MYF(0));
     init_client_errs();
     if (!mysql_port)
     {

=== modified file 'mysys/charset.c'
--- a/mysys/charset.c	2009-06-10 08:59:49 +0000
+++ b/mysys/charset.c	2009-09-11 17:24:20 +0000
@@ -321,7 +321,6 @@ static int add_collation(CHARSET_INFO *c
 #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,63 +398,50 @@ 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
+/* Initialization part 1: Load the compiled charsets. */
+void load_compiled_charsets(myf myflags)
 {
-  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(myflags);
+      
+  /* 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)-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;
+      if (cs[0]->ctype)
+        if (init_state_maps(*cs))
+          *cs= NULL;
     }
-    pthread_mutex_unlock(&THR_LOCK_charset);
   }
-  return error;
+
+  return FALSE;
+}
+
+
+/* 
+   Initialization part 2: Load the Index file from the charsets_dir directory. 
+*/
+my_bool load_available_charsets(myf myflags)
+{
+  char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
+
+  strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
+  return my_read_charset_file(fname,myflags);
 }
 
 
 void free_charsets(void)
 {
-  charset_initialized=0;
 }
 
 
 uint get_collation_number(const char *name)
 {
-  init_available_charsets(MYF(0));
   return get_collation_number_internal(name);
 }
 
@@ -463,7 +449,6 @@ uint get_collation_number(const char *na
 uint get_charset_number(const char *charset_name, uint cs_flags)
 {
   CHARSET_INFO **cs;
-  init_available_charsets(MYF(0));
   
   for (cs= all_charsets;
        cs < all_charsets+array_elements(all_charsets)-1 ;
@@ -480,7 +465,6 @@ uint get_charset_number(const char *char
 const char *get_charset_name(uint charset_number)
 {
   CHARSET_INFO *cs;
-  init_available_charsets(MYF(0));
 
   cs=all_charsets[charset_number];
   if (cs && (cs->number == charset_number) && cs->name )
@@ -538,8 +522,6 @@ CHARSET_INFO *get_charset(uint cs_number
   if (cs_number == default_charset_info->number)
     return default_charset_info;
 
-  (void) init_available_charsets(MYF(0));	/* If it isn't initialized */
-  
   if (!cs_number || cs_number >= array_elements(all_charsets)-1)
     return NULL;
   
@@ -560,7 +542,6 @@ CHARSET_INFO *get_charset_by_name(const 
 {
   uint cs_number;
   CHARSET_INFO *cs;
-  (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;
@@ -585,8 +566,6 @@ CHARSET_INFO *get_charset_by_csname(cons
   DBUG_ENTER("get_charset_by_csname");
   DBUG_PRINT("enter",("name: '%s'", cs_name));
 
-  (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;
 

=== modified file 'mysys/my_init.c'
--- a/mysys/my_init.c	2009-07-10 23:12:13 +0000
+++ b/mysys/my_init.c	2009-09-11 17:24:20 +0000
@@ -77,6 +77,7 @@ my_bool my_init(void)
   my_umask= 0660;                       /* Default umask for new files */
   my_umask_dir= 0700;                   /* Default umask for new directories */
   init_glob_errs();
+  load_compiled_charsets(MYF(0));
 #if defined(THREAD)
   if (my_thread_global_init())
     return 1;

=== modified file 'netware/libmysqlmain.c'
--- a/netware/libmysqlmain.c	2003-01-31 23:42:26 +0000
+++ b/netware/libmysqlmain.c	2009-09-11 17:24:20 +0000
@@ -30,8 +30,6 @@ int _NonAppStart(void *NLMHandle, void *
   const char **messages)
 {
   mysql_server_init(0, NULL, NULL);
-  
-  init_available_charsets(MYF(0));
 
   return 0;
 }

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-09-10 07:40:57 +0000
+++ b/sql/mysqld.cc	2009-09-11 17:24:20 +0000
@@ -3268,6 +3268,7 @@ static int init_common_variables(const c
   defaults_argc=argc;
   if (get_options(&defaults_argc, defaults_argv))
     return 1;
+  load_available_charsets(MYF(0));
   set_server_version();
 
   DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,


Attachment: [text/bzr-bundle] bzr/staale.smedseng@sun.com-20090911172420-4ypxcjyuisigv626.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (staale.smedseng:3120) Bug#45058Staale Smedseng11 Sep