Commit 5847be8c authored by Alexander Barkov's avatar Alexander Barkov

Bug#42649 THR_LOCK_charset global mutex abused by InnoDB

The patch was originally proposed by Mikael and reviewed by Bar.
parent e0d74efd
...@@ -494,29 +494,40 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) ...@@ -494,29 +494,40 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
{ {
char buf[FN_REFLEN]; char buf[FN_REFLEN];
CHARSET_INFO *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 ((cs= all_charsets[cs_number])) 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); strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
my_read_charset_file(buf,flags); my_read_charset_file(buf,flags);
} }
cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL;
} if (cs->state & MY_CS_AVAILABLE)
if (cs && !(cs->state & MY_CS_READY)) {
{ 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))) if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) ||
cs= NULL; (cs->coll->init && cs->coll->init(cs, cs_alloc)))
cs= NULL;
else
cs->state|= MY_CS_READY;
}
}
else else
cs->state|= MY_CS_READY; cs= NULL;
pthread_mutex_unlock(&THR_LOCK_charset);
} }
pthread_mutex_unlock(&THR_LOCK_charset);
return cs; return cs;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment