summaryrefslogtreecommitdiff
blob: aba2f29e864b068dc2c9429acf4d8f3dc9ae996b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Revert the changes from upstream bug 45058 for charset boot that broke akonadi.

X-Patch-URL: https://bugzilla.redhat.com/attachment.cgi?id=395215&action=diff&context=patch&collapsed=&headers=1&format=raw
X-Redhat-Bug-URL: https://bugzilla.redhat.com/show_bug.cgi?id=566547#c11

--- mysql-5.1.44.orig/include/my_sys.h	2010-02-04 06:37:06.000000000 -0500
+++ mysql-5.1.44.orig/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);
--- mysql-5.1.44.orig/libmysql/libmysql.c	2010-02-04 06:37:07.000000000 -0500
+++ mysql-5.1.44.orig/libmysql/libmysql.c	2010-02-19 23:13:48.000000000 -0500
@@ -211,6 +211,7 @@ 
   }
   else
   {
+    free_charsets();
     mysql_thread_end();
   }
 
--- mysql-5.1.44.orig/mysys/charset.c	2010-02-04 06:38:50.000000000 -0500
+++ mysql-5.1.44.orig/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;
--- mysql-5.1.44.orig/mysys/my_init.c	2010-02-04 06:38:51.000000000 -0500
+++ mysql-5.1.44.orig/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();
 
--- mysql-5.1.44.orig/netware/libmysqlmain.c	2010-02-04 06:38:51.000000000 -0500
+++ mysql-5.1.44.orig/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;
 }
--- mysql-5.1.44.orig/sql/mysqld.cc	2010-02-04 06:39:50.000000000 -0500
+++ mysql-5.1.44.orig/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