summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2010-02-02 12:22:17 +0300
committerKonstantin Osipov <kostja@sun.com>2010-02-02 12:22:17 +0300
commit3147bdd0ac34a5c62158b8c28da6ca77e0901f08 (patch)
tree919a1043e20b3f1f6a58331ae90a4a9529b0ab5e /mysys
parent2c6015e8dc962bef8f353af920581d9b6bd7fd82 (diff)
parent5bce1e06429c3d58457051f0c439f130609df375 (diff)
downloadmariadb-git-3147bdd0ac34a5c62158b8c28da6ca77e0901f08.tar.gz
Merge next-mr -> next-4284.
Diffstat (limited to 'mysys')
-rw-r--r--mysys/charset.c78
-rw-r--r--mysys/my_init.c1
-rw-r--r--mysys/my_thr_init.c10
-rw-r--r--mysys/my_winthread.c32
-rw-r--r--mysys/stacktrace.c21
5 files changed, 85 insertions, 57 deletions
diff --git a/mysys/charset.c b/mysys/charset.c
index f05e8c71297..0cd4fcff56c 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])
{
@@ -327,7 +328,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)
@@ -405,63 +405,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
- */
- mysql_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;
}
- mysql_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);
}
@@ -469,7 +443,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);
@@ -486,7 +460,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 )
@@ -544,7 +518,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;
@@ -566,7 +540,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;
@@ -591,7 +565,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 fa68bb2b1cb..8145dc6fb6a 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -208,7 +208,6 @@ void my_end(int infoflag)
my_print_open_files();
}
}
- free_charsets();
my_error_unregister_all();
my_once_free();
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index b3d7d63b197..a06bbb64c8b 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -24,9 +24,11 @@
#ifdef THREAD
pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
-mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open,
- THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_myisam, THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time;
+mysql_mutex_t THR_LOCK_malloc,THR_LOCK_open,
+ THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
+ THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time,
+ THR_LOCK_myisam_mmap;
+
mysql_cond_t THR_COND_threads;
uint THR_thread_count= 0;
uint my_thread_end_wait_time= 5;
@@ -214,6 +216,7 @@ my_bool my_thread_global_init(void)
mysql_mutex_init(key_THR_LOCK_lock, &THR_LOCK_lock, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_THR_LOCK_isam, &THR_LOCK_isam, MY_MUTEX_INIT_SLOW);
mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW);
+ mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_THR_LOCK_time, &THR_LOCK_time, MY_MUTEX_INIT_FAST);
@@ -282,6 +285,7 @@ void my_thread_global_end(void)
mysql_mutex_destroy(&THR_LOCK_lock);
mysql_mutex_destroy(&THR_LOCK_isam);
mysql_mutex_destroy(&THR_LOCK_myisam);
+ mysql_mutex_destroy(&THR_LOCK_myisam_mmap);
mysql_mutex_destroy(&THR_LOCK_heap);
mysql_mutex_destroy(&THR_LOCK_net);
mysql_mutex_destroy(&THR_LOCK_time);
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index f3d643975b3..6b7a51e7755 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
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 0b9e6eefcce..f1b96cd03da 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -60,7 +60,26 @@ void my_safe_print_str(const char* name, const char* val, int max_len)
fputc('\n', stderr);
}
-#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
+#if defined(HAVE_PRINTSTACK)
+
+/* Use Solaris' symbolic stack trace routine. */
+#include <ucontext.h>
+
+void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
+ ulong thread_stack __attribute__((unused)))
+{
+ if (printstack(fileno(stderr)) == -1)
+ fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n");
+ else
+ fprintf(stderr,
+ "Please read "
+ "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
+ "and follow instructions on how to resolve the stack trace.\n"
+ "Resolved stack trace is much more helpful in diagnosing the\n"
+ "problem, so please do resolve it\n");
+}
+
+#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#if BACKTRACE_DEMANGLE