Heya list

After installing KDE 4.4, I ran into the problem that Akonadi would not
start. With the help of krop on #akonadi, I found the following explanation:

A patch fixing MySQL bug 45058 was committed to MySQL 5.1.43 and 5.5.1
[1]. This was meant to address a race condition but also broke charset
handling somehow, making akonadiserver crash.

Redhat have a patch that reverts this change [2]. Of course, this
reintroduces the race condition but at least it makes Akonadi work again.

The Redhat patch is against MySQL 5.1.43. I successfully applied it to
MySQL 5.5.1 and am happy to report that Akonadi works for me as well now.

Attached is a patch that you can drop into
/usr/ports/databases/mysql55-server/files. Then, rebuild
databases/mysql-client55. The same file should work for MySQL 5.1 as well.

Once Redhat have confirmed that this works for them (or a better patch
has been found), this should be pushed into FreeBSD ports. Otherwise,
anyone upgrading to KDE 4.4 with Akonadi 1.3.1 (and using an up-to-date
MySQL port) will run into problems with Akonadi not starting.

- Bartosz

[1] http://bugs.mysql.com/bug.php?id=45058
[2] https://bugzilla.redhat.com/show_bug.cgi?id=566547#c11
--- include/my_sys.h.orig       2009-12-28 12:03:23.000000000 +0000
+++ include/my_sys.h    2010-02-20 16:21:32.000000000 +0000
@@ -978,6 +978,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);
--- libmysql/libmysql.c.orig    2009-12-28 12:03:24.000000000 +0000
+++ libmysql/libmysql.c 2010-02-20 16:21:32.000000000 +0000
@@ -211,6 +211,7 @@
   }
   else
   {
+    free_charsets();
     mysql_thread_end();
   }
 
--- mysys/charset.c.orig        2009-12-28 12:04:59.000000000 +0000
+++ mysys/charset.c     2010-02-20 16:21:32.000000000 +0000
@@ -328,6 +328,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)
@@ -405,37 +406,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);
 }
 
@@ -443,7 +470,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);
@@ -460,7 +487,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 )
@@ -518,7 +545,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))
     return NULL;
@@ -540,7 +567,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;
@@ -565,7 +592,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;
--- mysys/my_init.c.orig        2009-12-28 12:05:00.000000000 +0000
+++ mysys/my_init.c     2010-02-20 16:21:32.000000000 +0000
@@ -167,6 +167,7 @@
       my_print_open_files();
     }
   }
+  free_charsets();
   my_error_unregister_all();
   my_once_free();
 
--- netware/libmysqlmain.c.orig 2009-12-28 12:05:03.000000000 +0000
+++ netware/libmysqlmain.c      2010-02-20 16:21:32.000000000 +0000
@@ -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;
 }
--- sql/mysqld.cc.orig  2010-02-20 16:19:21.000000000 +0000
+++ sql/mysqld.cc       2010-02-20 16:21:32.000000000 +0000
@@ -1312,6 +1312,7 @@
   lex_free();                          /* Free some memory */
   item_create_cleanup();
   set_var_free();
+  free_charsets();
   if (!opt_noacl)
   {
 #ifdef HAVE_DLOPEN
_______________________________________________
kde-freebsd mailing list
kde-freebsd@kde.org
https://mail.kde.org/mailman/listinfo/kde-freebsd
See also http://freebsd.kde.org/ for latest information

Reply via email to