summaryrefslogtreecommitdiff
path: root/sql/sql_plugin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_plugin.cc')
-rw-r--r--sql/sql_plugin.cc114
1 files changed, 75 insertions, 39 deletions
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index c7f36014003..44b2a8220b3 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -269,6 +269,7 @@ struct st_bookmark
uint name_len;
int offset;
uint version;
+ bool loaded;
char key[1];
};
@@ -778,7 +779,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
if (global_system_variables.log_warnings > 2)
{
struct link_map *lm = (struct link_map*) plugin_dl.handle;
- sql_print_information("Loaded '%s' with offset 0x%lx", dl->str, lm->l_addr);
+ sql_print_information("Loaded '%s' with offset 0x%zx", dl->str, (size_t)lm->l_addr);
}
#endif
@@ -981,8 +982,8 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc,
*plugin= pi;
#endif
pi->ref_count++;
- DBUG_PRINT("lock",("thd: 0x%lx plugin: \"%s\" LOCK ref_count: %d",
- (long) current_thd, pi->name.str, pi->ref_count));
+ DBUG_PRINT("lock",("thd: %p plugin: \"%s\" LOCK ref_count: %d",
+ current_thd, pi->name.str, pi->ref_count));
if (lex)
insert_dynamic(&lex->plugins, (uchar*)&plugin);
@@ -1178,6 +1179,13 @@ err:
DBUG_RETURN(errs > 0 || oks + dupes == 0);
}
+static void plugin_variables_deinit(struct st_plugin_int *plugin)
+{
+
+ for (sys_var *var= plugin->system_vars; var; var= var->next)
+ (*var->test_load)= FALSE;
+ mysql_del_sys_var_chain(plugin->system_vars);
+}
static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
{
@@ -1229,8 +1237,7 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
if (ref_check && plugin->ref_count)
sql_print_error("Plugin '%s' has ref_count=%d after deinitialization.",
plugin->name.str, plugin->ref_count);
-
- mysql_del_sys_var_chain(plugin->system_vars);
+ plugin_variables_deinit(plugin);
}
static void plugin_del(struct st_plugin_int *plugin)
@@ -1335,8 +1342,8 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
DBUG_ASSERT(pi->ref_count);
pi->ref_count--;
- DBUG_PRINT("lock",("thd: 0x%lx plugin: \"%s\" UNLOCK ref_count: %d",
- (long) current_thd, pi->name.str, pi->ref_count));
+ DBUG_PRINT("lock",("thd: %p plugin: \"%s\" UNLOCK ref_count: %d",
+ current_thd, pi->name.str, pi->ref_count));
if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count)
reap_needed= true;
@@ -1393,10 +1400,10 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
mysql_mutex_unlock(&LOCK_plugin);
- mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+ mysql_prlock_wrlock(&LOCK_system_variables_hash);
if (test_plugin_options(tmp_root, plugin, argc, argv))
state= PLUGIN_IS_DISABLED;
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
if (options_only || state == PLUGIN_IS_DISABLED)
{
@@ -1449,7 +1456,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
err:
if (ret)
- mysql_del_sys_var_chain(plugin->system_vars);
+ plugin_variables_deinit(plugin);
mysql_mutex_lock(&LOCK_plugin);
plugin->state= state;
@@ -1542,19 +1549,23 @@ int plugin_init(int *argc, char **argv, int flags)
init_alloc_root(&plugin_vars_mem_root, 4096, 4096, MYF(0));
init_alloc_root(&tmp_root, 4096, 4096, MYF(0));
- if (my_hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
+ if (my_hash_init(&bookmark_hash, &my_charset_bin, 32, 0, 0,
get_bookmark_hash_key, NULL, HASH_UNIQUE))
goto err;
+ /*
+ The 80 is from 2016-04-27 when we had 71 default plugins
+ Big enough to avoid many mallocs even in future
+ */
if (my_init_dynamic_array(&plugin_dl_array,
sizeof(struct st_plugin_dl *), 16, 16, MYF(0)) ||
my_init_dynamic_array(&plugin_array,
- sizeof(struct st_plugin_int *), 16, 16, MYF(0)))
+ sizeof(struct st_plugin_int *), 80, 32, MYF(0)))
goto err;
for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
{
- if (my_hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0,
+ if (my_hash_init(&plugin_hash[i], system_charset_info, 32, 0, 0,
get_plugin_hash_key, NULL, HASH_UNIQUE))
goto err;
}
@@ -1766,7 +1777,7 @@ static void plugin_load(MEM_ROOT *tmp_root)
TABLE *table;
READ_RECORD read_record_info;
int error;
- THD *new_thd= new THD;
+ THD *new_thd= new THD(0);
bool result;
DBUG_ENTER("plugin_load");
@@ -1797,7 +1808,8 @@ static void plugin_load(MEM_ROOT *tmp_root)
goto end;
}
- if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE))
+ if (init_read_record(&read_record_info, new_thd, table, NULL, NULL, 1, 0,
+ FALSE))
{
sql_print_error("Could not initialize init_read_record; Plugins not "
"loaded");
@@ -2158,8 +2170,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
See also mysql_uninstall_plugin() and initialize_audit_plugin()
*/
-
- mysql_audit_acquire_plugins(thd, event_class_mask);
+ if (mysql_audit_general_enabled())
+ mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
error= plugin_add(thd->mem_root, name, &dl, REPORT_TO_USER);
@@ -2305,7 +2317,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
See also mysql_install_plugin() and initialize_audit_plugin()
*/
- mysql_audit_acquire_plugins(thd, event_class_mask);
+ if (mysql_audit_general_enabled())
+ mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
@@ -2791,20 +2804,22 @@ static void update_func_double(THD *thd, struct st_mysql_sys_var *var,
System Variables support
****************************************************************************/
-
-sys_var *find_sys_var(THD *thd, const char *str, uint length)
+sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
+ bool throw_error, bool locked)
{
sys_var *var;
sys_var_pluginvar *pi= NULL;
plugin_ref plugin;
- DBUG_ENTER("find_sys_var");
+ DBUG_ENTER("find_sys_var_ex");
+ DBUG_PRINT("enter", ("var '%.*s'", (int)length, str));
- mysql_mutex_lock(&LOCK_plugin);
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ if (!locked)
+ mysql_mutex_lock(&LOCK_plugin);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
if ((var= intern_find_sys_var(str, length)) &&
(pi= var->cast_pluginvar()))
{
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
LEX *lex= thd ? thd->lex : 0;
if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
var= NULL; /* failed to lock it, it must be uninstalling */
@@ -2817,15 +2832,21 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
}
}
else
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
- mysql_mutex_unlock(&LOCK_plugin);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
+ if (!locked)
+ mysql_mutex_unlock(&LOCK_plugin);
- if (!var)
- my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
+ if (!throw_error && !var)
+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (int)length, (char*) str);
DBUG_RETURN(var);
}
+sys_var *find_sys_var(THD *thd, const char *str, size_t length)
+{
+ return find_sys_var_ex(thd, str, length, false, false);
+}
+
/*
called by register_var, construct_options and test_plugin_options.
Returns the 'bookmark' for the named variable.
@@ -3040,9 +3061,9 @@ 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)
{
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
sync_dynamic_session_variables(thd, global_lock);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
}
DBUG_RETURN((uchar*)thd->variables.dynamic_variables_ptr + offset);
}
@@ -3157,7 +3178,7 @@ static void cleanup_variables(struct system_variables *vars)
st_bookmark *v;
uint idx;
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
for (idx= 0; idx < bookmark_hash.records; idx++)
{
v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
@@ -3176,7 +3197,7 @@ static void cleanup_variables(struct system_variables *vars)
*ptr= NULL;
}
}
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
DBUG_ASSERT(vars->table_plugin == NULL);
DBUG_ASSERT(vars->tmp_table_plugin == NULL);
@@ -3241,8 +3262,8 @@ static void plugin_vars_free_values(sys_var *vars)
{
/* Free the string from global_system_variables. */
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
- DBUG_PRINT("plugin", ("freeing value for: '%s' addr: 0x%lx",
- var->name.str, (long) valptr));
+ DBUG_PRINT("plugin", ("freeing value for: '%s' addr: %p",
+ var->name.str, valptr));
my_free(*valptr);
*valptr= NULL;
}
@@ -3305,14 +3326,14 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type)
{
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
case PLUGIN_VAR_BOOL:
- thd->sys_var_tmp.my_bool_value= option.def_value;
+ thd->sys_var_tmp.my_bool_value= (my_bool)option.def_value;
return (uchar*) &thd->sys_var_tmp.my_bool_value;
case PLUGIN_VAR_INT:
- thd->sys_var_tmp.int_value= option.def_value;
+ thd->sys_var_tmp.int_value= (int)option.def_value;
return (uchar*) &thd->sys_var_tmp.int_value;
case PLUGIN_VAR_LONG:
case PLUGIN_VAR_ENUM:
- thd->sys_var_tmp.long_value= option.def_value;
+ thd->sys_var_tmp.long_value= (long)option.def_value;
return (uchar*) &thd->sys_var_tmp.long_value;
case PLUGIN_VAR_LONGLONG:
case PLUGIN_VAR_SET:
@@ -3931,6 +3952,14 @@ my_bool mark_changed(int, const struct my_option *opt, char *)
}
/**
+ It is always false to mark global plugin variable unloaded just to be
+ safe because we have no way now to know truth about them.
+
+ TODO: make correct mechanism for global plugin variables
+*/
+static bool static_unload= FALSE;
+
+/**
Create and register system variables supplied from the plugin and
assigns initial values from corresponding command line arguments.
@@ -4007,9 +4036,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
tmp_backup[tmp->nbackups++].save(&o->name);
if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
+ {
varname= var->key + 1;
+ var->loaded= TRUE;
+ }
else
{
+ var= NULL;
len= tmp->name.length + strlen(o->name) + 2;
varname= (char*) alloc_root(mem_root, len);
strxmov(varname, tmp->name.str, "-", o->name, NullS);
@@ -4017,6 +4050,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
convert_dash_to_underscore(varname, len-1);
}
v= new (mem_root) sys_var_pluginvar(&chain, varname, tmp, o);
+ v->test_load= (var ? &var->loaded : &static_unload);
+ DBUG_ASSERT(static_unload == FALSE);
+
if (!(o->flags & PLUGIN_VAR_NOCMDOPT))
{
// update app_type, used for I_S.SYSTEM_VARIABLES
@@ -4217,10 +4253,10 @@ int thd_key_create(MYSQL_THD_KEY_T *key)
PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT;
char namebuf[256];
snprintf(namebuf, sizeof(namebuf), "%u", thd_key_no++);
- mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+ mysql_prlock_wrlock(&LOCK_system_variables_hash);
// non-letters in the name as an extra safety
st_bookmark *bookmark= register_var("\a\v\a\t\a\r", namebuf, flags);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
if (bookmark)
{
*key= bookmark->offset;