diff options
author | Alexander Barkov <bar@mysql.com> | 2009-04-07 11:48:38 +0500 |
---|---|---|
committer | Alexander Barkov <bar@mysql.com> | 2009-04-07 11:48:38 +0500 |
commit | 5847be8c9ac91e746af591d44ff01b72d9f87adc (patch) | |
tree | 92cb9a89fb6eee55d4c12e4d29a8457729f7b278 /mysys/charset.c | |
parent | e0d74efd85778495628acebb16bad435e56d6d95 (diff) | |
download | mariadb-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.c | 41 |
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; } |