diff options
-rw-r--r-- | sql/sql_plugin.cc | 125 | ||||
-rw-r--r-- | sql/sql_plugin.h | 1 | ||||
-rw-r--r-- | sql/sql_show.cc | 11 |
3 files changed, 77 insertions, 60 deletions
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 0158ab7d206..850d44f83e3 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2955,6 +2955,70 @@ static st_bookmark *register_var(const char *plugin, const char *name, return result; } + +void sync_dynamic_session_variables(THD* thd, bool global_lock) +{ + uint idx; + + thd->variables.dynamic_variables_ptr= (char*) + my_realloc(thd->variables.dynamic_variables_ptr, + global_variables_dynamic_size, + MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); + + if (global_lock) + mysql_mutex_lock(&LOCK_global_system_variables); + + mysql_mutex_assert_owner(&LOCK_global_system_variables); + + memcpy(thd->variables.dynamic_variables_ptr + + thd->variables.dynamic_variables_size, + global_system_variables.dynamic_variables_ptr + + thd->variables.dynamic_variables_size, + global_system_variables.dynamic_variables_size - + thd->variables.dynamic_variables_size); + + /* + now we need to iterate through any newly copied 'defaults' + and if it is a string type with MEMALLOC flag, we need to strdup + */ + for (idx= 0; idx < bookmark_hash.records; idx++) + { + sys_var_pluginvar *pi; + sys_var *var; + st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx); + + if (v->version <= thd->variables.dynamic_variables_version) + continue; /* already in thd->variables */ + + if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) || + !(pi= var->cast_pluginvar()) || + v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags)) + continue; + + /* Here we do anything special that may be required of the data types */ + + if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR && + pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC) + { + int offset= ((thdvar_str_t *)(pi->plugin_var))->offset; + char **pp= (char**) (thd->variables.dynamic_variables_ptr + offset); + if (*pp) + *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE)); + } + } + + if (global_lock) + mysql_mutex_unlock(&LOCK_global_system_variables); + + thd->variables.dynamic_variables_version= + global_system_variables.dynamic_variables_version; + thd->variables.dynamic_variables_head= + global_system_variables.dynamic_variables_head; + thd->variables.dynamic_variables_size= + global_system_variables.dynamic_variables_size; +} + + /* returns a pointer to the memory which holds the thd-local variable or a pointer to the global variable if thd==null. @@ -2976,67 +3040,8 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) if (!thd->variables.dynamic_variables_ptr || (uint)offset > thd->variables.dynamic_variables_head) { - uint idx; - mysql_rwlock_rdlock(&LOCK_system_variables_hash); - - thd->variables.dynamic_variables_ptr= (char*) - my_realloc(thd->variables.dynamic_variables_ptr, - global_variables_dynamic_size, - MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); - - if (global_lock) - mysql_mutex_lock(&LOCK_global_system_variables); - - mysql_mutex_assert_owner(&LOCK_global_system_variables); - - memcpy(thd->variables.dynamic_variables_ptr + - thd->variables.dynamic_variables_size, - global_system_variables.dynamic_variables_ptr + - thd->variables.dynamic_variables_size, - global_system_variables.dynamic_variables_size - - thd->variables.dynamic_variables_size); - - /* - now we need to iterate through any newly copied 'defaults' - and if it is a string type with MEMALLOC flag, we need to strdup - */ - for (idx= 0; idx < bookmark_hash.records; idx++) - { - sys_var_pluginvar *pi; - sys_var *var; - st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx); - - if (v->version <= thd->variables.dynamic_variables_version) - continue; /* already in thd->variables */ - - if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) || - !(pi= var->cast_pluginvar()) || - v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags)) - continue; - - /* Here we do anything special that may be required of the data types */ - - if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR && - pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC) - { - int offset= ((thdvar_str_t *)(pi->plugin_var))->offset; - char **pp= (char**) (thd->variables.dynamic_variables_ptr + offset); - if (*pp) - *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE)); - } - } - - if (global_lock) - mysql_mutex_unlock(&LOCK_global_system_variables); - - thd->variables.dynamic_variables_version= - global_system_variables.dynamic_variables_version; - thd->variables.dynamic_variables_head= - global_system_variables.dynamic_variables_head; - thd->variables.dynamic_variables_size= - global_system_variables.dynamic_variables_size; - + sync_dynamic_session_variables(thd, global_lock); mysql_rwlock_unlock(&LOCK_system_variables_hash); } DBUG_RETURN((uchar*)thd->variables.dynamic_variables_ptr + offset); diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index efa48b22ce8..9483fc8d9b3 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -190,4 +190,5 @@ extern bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, extern bool plugin_dl_foreach(THD *thd, const LEX_STRING *dl, plugin_foreach_func *func, void *arg); +extern void sync_dynamic_session_variables(THD* thd, bool global_lock); #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8ec44bad966..ae3874506dd 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7209,6 +7209,17 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) COND *partial_cond= make_cond_for_info_schema(thd, cond, tables); mysql_rwlock_rdlock(&LOCK_system_variables_hash); + + /* + Avoid recursive LOCK_system_variables_hash acquisition in + intern_sys_var_ptr() by pre-syncing dynamic session variables. + */ + if (scope == OPT_SESSION && + (!thd->variables.dynamic_variables_ptr || + global_system_variables.dynamic_variables_head > + thd->variables.dynamic_variables_head)) + sync_dynamic_session_variables(thd, true); + res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope), scope, NULL, "", tables->table, upper_case_names, partial_cond); |