summaryrefslogtreecommitdiff
path: root/mysys/charset.c
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mysql.com>2009-04-07 11:48:38 +0500
committerAlexander Barkov <bar@mysql.com>2009-04-07 11:48:38 +0500
commit5847be8c9ac91e746af591d44ff01b72d9f87adc (patch)
tree92cb9a89fb6eee55d4c12e4d29a8457729f7b278 /mysys/charset.c
parente0d74efd85778495628acebb16bad435e56d6d95 (diff)
downloadmariadb-git-5847be8c9ac91e746af591d44ff01b72d9f87adc.tar.gz
Bug#42649 THR_LOCK_charset global mutex abused by InnoDB
The patch was originally proposed by Mikael and reviewed by Bar.
Diffstat (limited to 'mysys/charset.c')
-rw-r--r--mysys/charset.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/mysys/charset.c b/mysys/charset.c
index e61995de1d8..7a7ef0ad3ea 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -494,29 +494,40 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
{
char buf[FN_REFLEN];
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 ((cs= all_charsets[cs_number]))
{
- if (!(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED))
+ if (cs->state & MY_CS_READY) /* if CS is already initialized */
+ return 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 (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */
{
strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
my_read_charset_file(buf,flags);
}
- cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL;
- }
- if (cs && !(cs->state & MY_CS_READY))
- {
- if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) ||
- (cs->coll->init && cs->coll->init(cs, cs_alloc)))
- cs= NULL;
+
+ if (cs->state & MY_CS_AVAILABLE)
+ {
+ if (!(cs->state & MY_CS_READY))
+ {
+ if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) ||
+ (cs->coll->init && cs->coll->init(cs, cs_alloc)))
+ cs= NULL;
+ else
+ cs->state|= MY_CS_READY;
+ }
+ }
else
- cs->state|= MY_CS_READY;
+ cs= NULL;
+
+ pthread_mutex_unlock(&THR_LOCK_charset);
}
- pthread_mutex_unlock(&THR_LOCK_charset);
return cs;
}