WL#2936
"Server variables for plugins" Post review fixes. client/mysql.cc: wl2936 "Plugin server variables" post review fixes compile fix. app_type is now a void* and it isn't actually used here. include/my_getopt.h: wl2936 "Plugin server variables" post review fixes make app_type into a void*. This also required changes to client/mysql.cc and storage/ndb/src/mgmsrv/InitConfigFileParser.cpp in order to compile. include/my_global.h: wl2936 "Plugin server variables" post-review fixes declare compile_time_assert() macro. (provided by serg) include/mysql/plugin.h: wl2936 "Plugin server variables" post review fixes Add comments mysys/array.c: wl2936 "Plugin server variables" post review fixes mysys/typelib.c: wl2936 "Plugin server variables" post review fixes find_typeset() should not alter string sql/set_var.cc: wl2936 "Plugin server variables" post review fixes remove unnecessary code. sql/sql_class.cc: wl2936 "Plugin server variables" post review fixes explicitly declare export style for functions. sql/sql_lex.cc: wl2936 "Plugin server variables" post review fixes enforce that lex::plugins_static_buffer is declared immediately after lex::plugins. sql/sql_plugin.cc: wl2936 "Plugin Server variables" post review fixes sys_var_pluginvar does not need st_plugin_int at construction. remove debug code which was accidentially committed. add comments. fix mutex lock order. sql/sql_plugin.h: wl2936 "Plugin server variables" post review fixes add comment and macro to compare plugin_refs sql/table.cc: wl2936 "plugin server variables" post review fixes remove unneccessary unlock and variable. add checks for legacy type validity storage/ndb/src/mgmsrv/InitConfigFileParser.cpp: wl2936 "plugin server variables" post review fixes fix compile failure now that my_option::app_type is a void*
This commit is contained in:
parent
1fc7f2117b
commit
eac12b6587
@ -743,7 +743,7 @@ static struct my_option my_long_options[] =
|
|||||||
"Number of seconds before connection timeout.",
|
"Number of seconds before connection timeout.",
|
||||||
(gptr*) &opt_connect_timeout,
|
(gptr*) &opt_connect_timeout,
|
||||||
(gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
|
(gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
|
||||||
0, 1},
|
0, 0},
|
||||||
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
|
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
|
||||||
"Max packet length to send to, or receive from server",
|
"Max packet length to send to, or receive from server",
|
||||||
(gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, GET_ULONG,
|
(gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, GET_ULONG,
|
||||||
|
@ -54,7 +54,7 @@ struct my_option
|
|||||||
longlong max_value; /* Max allowed value */
|
longlong max_value; /* Max allowed value */
|
||||||
longlong sub_size; /* Subtract this from given value */
|
longlong sub_size; /* Subtract this from given value */
|
||||||
long block_size; /* Value should be a mult. of this */
|
long block_size; /* Value should be a mult. of this */
|
||||||
long app_type; /* To be used by an application */
|
void *app_type; /* To be used by an application */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
|
typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
|
||||||
|
@ -458,6 +458,14 @@ C_MODE_END
|
|||||||
*/
|
*/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* an assert that works at compile-time. only for constant expression */
|
||||||
|
#define compile_time_assert(X) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
char compile_time_assert[(X) ? 1 : -1] \
|
||||||
|
__attribute__ ((unused)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/* Go around some bugs in different OS and compilers */
|
/* Go around some bugs in different OS and compilers */
|
||||||
#if defined (HPUX11) && defined(_LARGEFILE_SOURCE)
|
#if defined (HPUX11) && defined(_LARGEFILE_SOURCE)
|
||||||
#define _LARGEFILE64_SOURCE
|
#define _LARGEFILE64_SOURCE
|
||||||
|
@ -122,9 +122,43 @@ typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, char *)
|
|||||||
struct st_mysql_sys_var;
|
struct st_mysql_sys_var;
|
||||||
struct st_mysql_value;
|
struct st_mysql_value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
SYNOPSIS
|
||||||
|
(*mysql_var_check_func)()
|
||||||
|
thd thread handle
|
||||||
|
var dynamic variable being altered
|
||||||
|
save pointer to temporary storage
|
||||||
|
value user provided value
|
||||||
|
RETURN
|
||||||
|
0 user provided value is OK and the update func may be called.
|
||||||
|
any other value indicates error.
|
||||||
|
|
||||||
|
This function should parse the user provided value and store in the
|
||||||
|
provided temporary storage any data as required by the update func.
|
||||||
|
There is sufficient space in the temporary storage to store a double.
|
||||||
|
Note that the update func may not be called if any other error occurs
|
||||||
|
so any memory allocated should be thread-local so that it may be freed
|
||||||
|
automatically at the end of the statement.
|
||||||
|
*/
|
||||||
|
|
||||||
typedef int (*mysql_var_check_func)(MYSQL_THD thd,
|
typedef int (*mysql_var_check_func)(MYSQL_THD thd,
|
||||||
struct st_mysql_sys_var *var,
|
struct st_mysql_sys_var *var,
|
||||||
void *save, struct st_mysql_value *value);
|
void *save, struct st_mysql_value *value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
SYNOPSIS
|
||||||
|
(*mysql_var_update_func)()
|
||||||
|
thd thread handle
|
||||||
|
var dynamic variable being altered
|
||||||
|
var_ptr pointer to dynamic variable
|
||||||
|
save pointer to temporary storage
|
||||||
|
RETURN
|
||||||
|
NONE
|
||||||
|
|
||||||
|
This function should use the validated value stored in the temporary store
|
||||||
|
and persist it in the provided pointer to the dynamic variable.
|
||||||
|
For example, strings may require memory to be allocated.
|
||||||
|
*/
|
||||||
typedef void (*mysql_var_update_func)(MYSQL_THD thd,
|
typedef void (*mysql_var_update_func)(MYSQL_THD thd,
|
||||||
struct st_mysql_sys_var *var,
|
struct st_mysql_sys_var *var,
|
||||||
void *var_ptr, void *save);
|
void *var_ptr, void *save);
|
||||||
@ -582,6 +616,10 @@ struct st_mysql_information_schema
|
|||||||
st_mysql_value struct for reading values from mysqld.
|
st_mysql_value struct for reading values from mysqld.
|
||||||
Used by server variables framework to parse user-provided values.
|
Used by server variables framework to parse user-provided values.
|
||||||
Will be used for arguments when implementing UDFs.
|
Will be used for arguments when implementing UDFs.
|
||||||
|
|
||||||
|
Note that val_str() returns a string in temporary memory
|
||||||
|
that will be freed at the end of statement. Copy the string
|
||||||
|
if you need it to persist.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MYSQL_VALUE_TYPE_STRING 0
|
#define MYSQL_VALUE_TYPE_STRING 0
|
||||||
|
@ -57,9 +57,10 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!init_alloc)
|
if (!init_alloc)
|
||||||
|
{
|
||||||
init_alloc=alloc_increment;
|
init_alloc=alloc_increment;
|
||||||
else
|
|
||||||
init_buffer= 0;
|
init_buffer= 0;
|
||||||
|
}
|
||||||
array->elements=0;
|
array->elements=0;
|
||||||
array->max_element=init_alloc;
|
array->max_element=init_alloc;
|
||||||
array->alloc_increment=alloc_increment;
|
array->alloc_increment=alloc_increment;
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const char field_separator=',';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Search after a string in a list of strings. Endspace in x is not compared.
|
Search after a string in a list of strings. Endspace in x is not compared.
|
||||||
|
|
||||||
@ -31,6 +33,7 @@
|
|||||||
If & 1 accept only whole names
|
If & 1 accept only whole names
|
||||||
If & 2 don't expand if half field
|
If & 2 don't expand if half field
|
||||||
If & 4 allow #number# as type
|
If & 4 allow #number# as type
|
||||||
|
If & 8 use ',' as string terminator
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
If part, uniq field is found and full_name == 0 then x is expanded
|
If part, uniq field is found and full_name == 0 then x is expanded
|
||||||
@ -60,16 +63,18 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name)
|
|||||||
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
|
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
|
||||||
{
|
{
|
||||||
for (i=x ;
|
for (i=x ;
|
||||||
*i && my_toupper(&my_charset_latin1,*i) ==
|
*i && (!(full_name & 8) || *i != field_separator) &&
|
||||||
|
my_toupper(&my_charset_latin1,*i) ==
|
||||||
my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
|
my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
|
||||||
if (! *j)
|
if (! *j)
|
||||||
{
|
{
|
||||||
while (*i == ' ')
|
while (*i == ' ')
|
||||||
i++; /* skip_end_space */
|
i++; /* skip_end_space */
|
||||||
if (! *i)
|
if (! *i || ((full_name & 8) && *i == field_separator))
|
||||||
DBUG_RETURN(pos+1);
|
DBUG_RETURN(pos+1);
|
||||||
}
|
}
|
||||||
if (! *i && (!*j || !(full_name & 1)))
|
if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
|
||||||
|
(!*j || !(full_name & 1)))
|
||||||
{
|
{
|
||||||
find++;
|
find++;
|
||||||
findpos=pos;
|
findpos=pos;
|
||||||
@ -120,8 +125,6 @@ const char *get_type(TYPELIB *typelib, uint nr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char field_separator=',';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create an integer value to represent the supplied comma-seperated
|
Create an integer value to represent the supplied comma-seperated
|
||||||
string where each string in the TYPELIB denotes a bit position.
|
string where each string in the TYPELIB denotes a bit position.
|
||||||
@ -157,9 +160,7 @@ my_ulonglong find_typeset(my_string x, TYPELIB *lib, int *err)
|
|||||||
(*err)++;
|
(*err)++;
|
||||||
i= x;
|
i= x;
|
||||||
while (*x && *x != field_separator) x++;
|
while (*x && *x != field_separator) x++;
|
||||||
if (*x)
|
if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
|
||||||
*x++= 0;
|
|
||||||
if ((find= find_type(i, lib, 2) - 1) < 0)
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
result|= (ULL(1) << find);
|
result|= (ULL(1) << find);
|
||||||
}
|
}
|
||||||
|
@ -2838,7 +2838,6 @@ int set_var_init()
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
fprintf(stderr, "failed to initialize system variables");
|
fprintf(stderr, "failed to initialize system variables");
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,18 +167,25 @@ Open_tables_state::Open_tables_state(ulong version_arg)
|
|||||||
reset_open_tables_state();
|
reset_open_tables_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following functions form part of the C plugin API
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C"
|
||||||
int thd_in_lock_tables(const THD *thd)
|
int thd_in_lock_tables(const THD *thd)
|
||||||
{
|
{
|
||||||
return test(thd->in_lock_tables);
|
return test(thd->in_lock_tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
int thd_tablespace_op(const THD *thd)
|
int thd_tablespace_op(const THD *thd)
|
||||||
{
|
{
|
||||||
return test(thd->tablespace_op);
|
return test(thd->tablespace_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
const char *thd_proc_info(THD *thd, const char *info)
|
const char *thd_proc_info(THD *thd, const char *info)
|
||||||
{
|
{
|
||||||
const char *old_info= thd->proc_info;
|
const char *old_info= thd->proc_info;
|
||||||
@ -186,16 +193,19 @@ const char *thd_proc_info(THD *thd, const char *info)
|
|||||||
return old_info;
|
return old_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
|
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
|
||||||
{
|
{
|
||||||
return (void **) thd->ha_data + hton->slot;
|
return (void **) thd->ha_data + hton->slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
long long thd_test_options(const THD *thd, long long test_options)
|
long long thd_test_options(const THD *thd, long long test_options)
|
||||||
{
|
{
|
||||||
return thd->options & test_options;
|
return thd->options & test_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
int thd_sql_command(const THD *thd)
|
int thd_sql_command(const THD *thd)
|
||||||
{
|
{
|
||||||
return (int) thd->lex->sql_command;
|
return (int) thd->lex->sql_command;
|
||||||
@ -216,6 +226,7 @@ int thd_sql_command(const THD *thd)
|
|||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
pointer to string
|
pointer to string
|
||||||
*/
|
*/
|
||||||
|
extern "C"
|
||||||
char *thd_security_context(THD *thd, char *buffer, int length,
|
char *thd_security_context(THD *thd, char *buffer, int length,
|
||||||
int max_query_len)
|
int max_query_len)
|
||||||
{
|
{
|
||||||
@ -268,6 +279,7 @@ char *thd_security_context(THD *thd, char *buffer, int length,
|
|||||||
return thd->strmake(str.ptr(), str.length());
|
return thd->strmake(str.ptr(), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Pass nominal parameters to Statement constructor only to ensure that
|
Pass nominal parameters to Statement constructor only to ensure that
|
||||||
the destructor works OK in case of error. The main_mem_root will be
|
the destructor works OK in case of error. The main_mem_root will be
|
||||||
|
@ -1745,6 +1745,9 @@ st_lex::st_lex()
|
|||||||
:result(0), yacc_yyss(0), yacc_yyvs(0),
|
:result(0), yacc_yyss(0), yacc_yyvs(0),
|
||||||
sql_command(SQLCOM_END)
|
sql_command(SQLCOM_END)
|
||||||
{
|
{
|
||||||
|
/* Check that plugins_static_buffer is declared immediately after plugins */
|
||||||
|
compile_time_assert((&plugins + 1) == (DYNAMIC_ARRAY*)plugins_static_buffer);
|
||||||
|
|
||||||
my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
|
my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
|
||||||
plugins_static_buffer,
|
plugins_static_buffer,
|
||||||
INITIAL_LEX_PLUGIN_LIST_SIZE,
|
INITIAL_LEX_PLUGIN_LIST_SIZE,
|
||||||
|
@ -161,9 +161,8 @@ public:
|
|||||||
{ TRASH(ptr_arg, size); }
|
{ TRASH(ptr_arg, size); }
|
||||||
|
|
||||||
sys_var_pluginvar(const char *name_arg,
|
sys_var_pluginvar(const char *name_arg,
|
||||||
struct st_plugin_int *plugin_arg,
|
|
||||||
struct st_mysql_sys_var *plugin_var_arg)
|
struct st_mysql_sys_var *plugin_var_arg)
|
||||||
:sys_var(name_arg), plugin(plugin_arg), plugin_var(plugin_var_arg) {}
|
:sys_var(name_arg), plugin_var(plugin_var_arg) {}
|
||||||
sys_var_pluginvar *cast_pluginvar() { return this; }
|
sys_var_pluginvar *cast_pluginvar() { return this; }
|
||||||
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
|
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
|
||||||
bool check_type(enum_var_type type)
|
bool check_type(enum_var_type type)
|
||||||
@ -631,11 +630,6 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
|
|||||||
#else
|
#else
|
||||||
if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
|
if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
//if (0x4620a20L == (long) plugin)
|
|
||||||
if (0x4656b10L == (long) plugin)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("debug",("trap"));
|
|
||||||
}
|
|
||||||
|
|
||||||
*plugin= pi;
|
*plugin= pi;
|
||||||
#endif
|
#endif
|
||||||
@ -656,6 +650,10 @@ plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO)
|
|||||||
LEX *lex= NULL;
|
LEX *lex= NULL;
|
||||||
plugin_ref rc;
|
plugin_ref rc;
|
||||||
DBUG_ENTER("plugin_lock");
|
DBUG_ENTER("plugin_lock");
|
||||||
|
/*
|
||||||
|
thd->lex may point to a nested LEX or a stored procedure LEX.
|
||||||
|
main_lex is tightly coupled to the thread.
|
||||||
|
*/
|
||||||
if (thd)
|
if (thd)
|
||||||
lex= !thd->lex ? &thd->main_lex : thd->lex;
|
lex= !thd->lex ? &thd->main_lex : thd->lex;
|
||||||
pthread_mutex_lock(&LOCK_plugin);
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
@ -767,11 +765,9 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
|||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
|
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
mysql_del_sys_var_chain(tmp.system_vars);
|
mysql_del_sys_var_chain(tmp.system_vars);
|
||||||
plugin_dl_del(dl);
|
goto err;
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
}
|
||||||
/* plugin was disabled */
|
/* plugin was disabled */
|
||||||
plugin_dl_del(dl);
|
plugin_dl_del(dl);
|
||||||
@ -939,7 +935,11 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
|
|||||||
pi->name.str, pi->ref_count));
|
pi->name.str, pi->ref_count));
|
||||||
if (lex)
|
if (lex)
|
||||||
{
|
{
|
||||||
/* remove one instance of this plugin from the use list */
|
/*
|
||||||
|
Remove one instance of this plugin from the use list.
|
||||||
|
We are searching backwards so that plugins locked last
|
||||||
|
could be unlocked faster - optimizing for LIFO semantics.
|
||||||
|
*/
|
||||||
for (i= lex->plugins.elements - 1; i >= 0; i--)
|
for (i= lex->plugins.elements - 1; i >= 0; i--)
|
||||||
if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*))
|
if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*))
|
||||||
{
|
{
|
||||||
@ -1283,6 +1283,7 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
|
|||||||
bzero(&tmp, sizeof(tmp));
|
bzero(&tmp, sizeof(tmp));
|
||||||
tmp.plugin= plugin;
|
tmp.plugin= plugin;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
rw_wrlock(&LOCK_system_variables_hash);
|
rw_wrlock(&LOCK_system_variables_hash);
|
||||||
|
|
||||||
if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL, true))
|
if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL, true))
|
||||||
@ -1293,6 +1294,7 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
rw_unlock(&LOCK_system_variables_hash);
|
rw_unlock(&LOCK_system_variables_hash);
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
|
|
||||||
DBUG_RETURN(result);;
|
DBUG_RETURN(result);;
|
||||||
}
|
}
|
||||||
@ -1445,6 +1447,11 @@ void plugin_shutdown(void)
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_plugin);
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
release any plugin references held but don't yet free
|
||||||
|
memory for dynamic variables as some plugins may still
|
||||||
|
want to reference their global variables.
|
||||||
|
*/
|
||||||
cleanup_variables(NULL, &global_system_variables, false);
|
cleanup_variables(NULL, &global_system_variables, false);
|
||||||
cleanup_variables(NULL, &max_system_variables, false);
|
cleanup_variables(NULL, &max_system_variables, false);
|
||||||
|
|
||||||
@ -1470,6 +1477,9 @@ void plugin_shutdown(void)
|
|||||||
}
|
}
|
||||||
reap_plugins();
|
reap_plugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
sql_print_warning("Forcing shutdown of %d plugins", count);
|
||||||
|
|
||||||
plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
|
plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
|
||||||
|
|
||||||
@ -1496,7 +1506,6 @@ void plugin_shutdown(void)
|
|||||||
plugin_deinitialize(plugins[i], false);
|
plugin_deinitialize(plugins[i], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_plugin);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We defer checking ref_counts until after all plugins are deinitialized
|
We defer checking ref_counts until after all plugins are deinitialized
|
||||||
@ -1511,15 +1520,24 @@ void plugin_shutdown(void)
|
|||||||
if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
|
if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
|
||||||
plugin_del(plugins[i]);
|
plugin_del(plugins[i]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Now we can deallocate all memory.
|
||||||
|
*/
|
||||||
|
#if defined(SAFE_MUTEX) && !defined(DBUG_OFF)
|
||||||
|
/* neccessary to avoid safe_mutex_assert_owner() trap */
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
|
#endif
|
||||||
cleanup_variables(NULL, &global_system_variables, true);
|
cleanup_variables(NULL, &global_system_variables, true);
|
||||||
cleanup_variables(NULL, &max_system_variables, true);
|
cleanup_variables(NULL, &max_system_variables, true);
|
||||||
|
#if defined(SAFE_MUTEX) && !defined(DBUG_OFF)
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
|
#endif
|
||||||
|
|
||||||
initialized= 0;
|
initialized= 0;
|
||||||
pthread_mutex_unlock(&LOCK_plugin);
|
|
||||||
pthread_mutex_destroy(&LOCK_plugin);
|
pthread_mutex_destroy(&LOCK_plugin);
|
||||||
|
|
||||||
|
my_afree(plugins);
|
||||||
}
|
}
|
||||||
my_afree(plugins);
|
|
||||||
|
|
||||||
/* Dispose of the memory */
|
/* Dispose of the memory */
|
||||||
|
|
||||||
@ -2007,12 +2025,13 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
|||||||
plugin_ref plugin;
|
plugin_ref plugin;
|
||||||
DBUG_ENTER("find_sys_var");
|
DBUG_ENTER("find_sys_var");
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
rw_rdlock(&LOCK_system_variables_hash);
|
rw_rdlock(&LOCK_system_variables_hash);
|
||||||
if ((var= intern_find_sys_var(str, length, false)) &&
|
if ((var= intern_find_sys_var(str, length, false)) &&
|
||||||
(pi= var->cast_pluginvar()))
|
(pi= var->cast_pluginvar()))
|
||||||
{
|
{
|
||||||
|
rw_unlock(&LOCK_system_variables_hash);
|
||||||
LEX *lex= thd ? ( !thd->lex ? &thd->main_lex : thd->lex ) : NULL;
|
LEX *lex= thd ? ( !thd->lex ? &thd->main_lex : thd->lex ) : NULL;
|
||||||
pthread_mutex_lock(&LOCK_plugin);
|
|
||||||
if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
|
if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
|
||||||
var= NULL; /* failed to lock it, it must be uninstalling */
|
var= NULL; /* failed to lock it, it must be uninstalling */
|
||||||
else
|
else
|
||||||
@ -2022,9 +2041,10 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
|||||||
var= NULL;
|
var= NULL;
|
||||||
intern_plugin_unlock(lex, plugin);
|
intern_plugin_unlock(lex, plugin);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_plugin);
|
|
||||||
}
|
}
|
||||||
rw_unlock(&LOCK_system_variables_hash);
|
else
|
||||||
|
rw_unlock(&LOCK_system_variables_hash);
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the variable exists but the plugin it is associated with is not ready
|
If the variable exists but the plugin it is associated with is not ready
|
||||||
@ -2183,7 +2203,7 @@ static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
|||||||
return (byte*) global_system_variables.dynamic_variables_ptr + offset;
|
return (byte*) global_system_variables.dynamic_variables_ptr + offset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dynamic_variables_size points to the largest valid offset
|
dynamic_variables_head points to the largest valid offset
|
||||||
*/
|
*/
|
||||||
if (!thd->variables.dynamic_variables_ptr ||
|
if (!thd->variables.dynamic_variables_ptr ||
|
||||||
(uint)offset > thd->variables.dynamic_variables_head)
|
(uint)offset > thd->variables.dynamic_variables_head)
|
||||||
@ -2208,8 +2228,6 @@ static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
|||||||
thd->variables.dynamic_variables_size,
|
thd->variables.dynamic_variables_size,
|
||||||
global_system_variables.dynamic_variables_size -
|
global_system_variables.dynamic_variables_size -
|
||||||
thd->variables.dynamic_variables_size);
|
thd->variables.dynamic_variables_size);
|
||||||
if (global_lock)
|
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
now we need to iterate through any newly copied 'defaults'
|
now we need to iterate through any newly copied 'defaults'
|
||||||
@ -2232,19 +2250,17 @@ static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
|||||||
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
|
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
|
||||||
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
|
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
|
||||||
{
|
{
|
||||||
char **pp;
|
char **pp= (char**) (thd->variables.dynamic_variables_ptr +
|
||||||
if (global_lock)
|
|
||||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
|
||||||
pp= (char**) (thd->variables.dynamic_variables_ptr +
|
|
||||||
*(int*)(pi->plugin_var + 1));
|
*(int*)(pi->plugin_var + 1));
|
||||||
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
|
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
|
||||||
*(int*)(pi->plugin_var + 1))))
|
*(int*)(pi->plugin_var + 1))))
|
||||||
*pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
|
*pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
|
||||||
if (global_lock)
|
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (global_lock)
|
||||||
|
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||||
|
|
||||||
thd->variables.dynamic_variables_version=
|
thd->variables.dynamic_variables_version=
|
||||||
global_system_variables.dynamic_variables_version;
|
global_system_variables.dynamic_variables_version;
|
||||||
thd->variables.dynamic_variables_head=
|
thd->variables.dynamic_variables_head=
|
||||||
@ -2817,7 +2833,7 @@ static int construct_options(MEM_ROOT *mem_root,
|
|||||||
|
|
||||||
options->name= optname;
|
options->name= optname;
|
||||||
options->comment= opt->comment;
|
options->comment= opt->comment;
|
||||||
options->app_type= (long) opt;
|
options->app_type= opt;
|
||||||
options->id= (options-1)->id + 1;
|
options->id= (options-1)->id + 1;
|
||||||
|
|
||||||
if (opt->flags & PLUGIN_VAR_THDLOCAL)
|
if (opt->flags & PLUGIN_VAR_THDLOCAL)
|
||||||
@ -2950,7 +2966,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((var= find_bookmark(tmp->plugin->name, o->name, o->flags)))
|
if ((var= find_bookmark(tmp->plugin->name, o->name, o->flags)))
|
||||||
v= new (mem_root) sys_var_pluginvar(var->name + 1, tmp, o);
|
v= new (mem_root) sys_var_pluginvar(var->name + 1, o);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len= strlen(tmp->plugin->name) + strlen(o->name) + 2;
|
len= strlen(tmp->plugin->name) + strlen(o->name) + 2;
|
||||||
@ -2962,10 +2978,15 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
|||||||
if (*p == '-')
|
if (*p == '-')
|
||||||
*p= '_';
|
*p= '_';
|
||||||
|
|
||||||
v= new (mem_root) sys_var_pluginvar(varname, tmp, o);
|
v= new (mem_root) sys_var_pluginvar(varname, o);
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(v); /* check that an object was actually constructed */
|
DBUG_ASSERT(v); /* check that an object was actually constructed */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add to the chain of variables.
|
||||||
|
Done like this for easier debugging so that the
|
||||||
|
pointer to v is not lost on optimized builds.
|
||||||
|
*/
|
||||||
v->chain_sys_var(&chain);
|
v->chain_sys_var(&chain);
|
||||||
}
|
}
|
||||||
if (chain.first)
|
if (chain.first)
|
||||||
|
@ -79,6 +79,11 @@ struct st_plugin_int
|
|||||||
sys_var *system_vars; /* server variables for this plugin */
|
sys_var *system_vars; /* server variables for this plugin */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
See intern_plugin_lock() for the explanation for the
|
||||||
|
conditionally defined plugin_ref type
|
||||||
|
*/
|
||||||
#ifdef DBUG_OFF
|
#ifdef DBUG_OFF
|
||||||
typedef struct st_plugin_int *plugin_ref;
|
typedef struct st_plugin_int *plugin_ref;
|
||||||
#define plugin_decl(pi) ((pi)->plugin)
|
#define plugin_decl(pi) ((pi)->plugin)
|
||||||
@ -86,6 +91,7 @@ typedef struct st_plugin_int *plugin_ref;
|
|||||||
#define plugin_data(pi,cast) ((cast)((pi)->data))
|
#define plugin_data(pi,cast) ((cast)((pi)->data))
|
||||||
#define plugin_name(pi) (&((pi)->name))
|
#define plugin_name(pi) (&((pi)->name))
|
||||||
#define plugin_state(pi) ((pi)->state)
|
#define plugin_state(pi) ((pi)->state)
|
||||||
|
#define plugin_equals(p1,p2) ((p1) == (p2))
|
||||||
#else
|
#else
|
||||||
typedef struct st_plugin_int **plugin_ref;
|
typedef struct st_plugin_int **plugin_ref;
|
||||||
#define plugin_decl(pi) ((pi)[0]->plugin)
|
#define plugin_decl(pi) ((pi)[0]->plugin)
|
||||||
@ -93,6 +99,7 @@ typedef struct st_plugin_int **plugin_ref;
|
|||||||
#define plugin_data(pi,cast) ((cast)((pi)[0]->data))
|
#define plugin_data(pi,cast) ((cast)((pi)[0]->data))
|
||||||
#define plugin_name(pi) (&((pi)[0]->name))
|
#define plugin_name(pi) (&((pi)[0]->name))
|
||||||
#define plugin_state(pi) ((pi)[0]->state)
|
#define plugin_state(pi) ((pi)[0]->state)
|
||||||
|
#define plugin_equals(p1,p2) ((p1) && (p2) && (p1)[0] == (p2)[0])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int (*plugin_type_init)(struct st_plugin_int *);
|
typedef int (*plugin_type_init)(struct st_plugin_int *);
|
||||||
|
26
sql/table.cc
26
sql/table.cc
@ -425,7 +425,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
Field **field_ptr, *reg_field;
|
Field **field_ptr, *reg_field;
|
||||||
const char **interval_array;
|
const char **interval_array;
|
||||||
enum legacy_db_type legacy_db_type;
|
enum legacy_db_type legacy_db_type;
|
||||||
handlerton *hton;
|
|
||||||
my_bitmap_map *bitmaps;
|
my_bitmap_map *bitmaps;
|
||||||
DBUG_ENTER("open_binary_frm");
|
DBUG_ENTER("open_binary_frm");
|
||||||
|
|
||||||
@ -456,11 +455,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
DBUG_PRINT("info", ("default_part_db_type = %u", head[61]));
|
DBUG_PRINT("info", ("default_part_db_type = %u", head[61]));
|
||||||
#endif
|
#endif
|
||||||
legacy_db_type= (enum legacy_db_type) (uint) *(head+3);
|
legacy_db_type= (enum legacy_db_type) (uint) *(head+3);
|
||||||
if ((hton= ha_checktype(thd, legacy_db_type, 0, 0)) != share->db_type())
|
DBUG_ASSERT(share->db_plugin == NULL);
|
||||||
{
|
/*
|
||||||
plugin_unlock(NULL, share->db_plugin);
|
if the storage engine is dynamic, no point in resolving it by its
|
||||||
share->db_plugin= ha_lock_engine(NULL, hton);
|
dynamically allocated legacy_db_type. We will resolve it later by name.
|
||||||
}
|
*/
|
||||||
|
if (legacy_db_type > DB_TYPE_UNKNOWN &&
|
||||||
|
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
|
||||||
|
share->db_plugin= ha_lock_engine(NULL,
|
||||||
|
ha_checktype(thd, legacy_db_type, 0, 0));
|
||||||
share->db_create_options= db_create_options= uint2korr(head+30);
|
share->db_create_options= db_create_options= uint2korr(head+30);
|
||||||
share->db_options_in_use= share->db_create_options;
|
share->db_options_in_use= share->db_create_options;
|
||||||
share->mysql_version= uint4korr(head+51);
|
share->mysql_version= uint4korr(head+51);
|
||||||
@ -620,8 +623,17 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
uint str_db_type_length= uint2korr(next_chunk);
|
uint str_db_type_length= uint2korr(next_chunk);
|
||||||
LEX_STRING name= { next_chunk + 2, str_db_type_length };
|
LEX_STRING name= { next_chunk + 2, str_db_type_length };
|
||||||
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
|
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
|
||||||
if (tmp_plugin != NULL)
|
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
|
||||||
{
|
{
|
||||||
|
if (legacy_db_type > DB_TYPE_UNKNOWN &&
|
||||||
|
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
|
||||||
|
legacy_db_type != ha_legacy_type(
|
||||||
|
plugin_data(tmp_plugin, handlerton *)))
|
||||||
|
{
|
||||||
|
/* bad file, legacy_db_type did not match the name */
|
||||||
|
my_free(buff, MYF(0));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
tmp_plugin is locked with a local lock.
|
tmp_plugin is locked with a local lock.
|
||||||
we unlock the old value of share->db_plugin before
|
we unlock the old value of share->db_plugin before
|
||||||
|
@ -612,10 +612,11 @@ static
|
|||||||
my_bool
|
my_bool
|
||||||
parse_mycnf_opt(int, const struct my_option * opt, char * value)
|
parse_mycnf_opt(int, const struct my_option * opt, char * value)
|
||||||
{
|
{
|
||||||
|
long *app_type= (long*) &opt->app_type;
|
||||||
if(opt->comment)
|
if(opt->comment)
|
||||||
((struct my_option *)opt)->app_type++;
|
(*app_type)++;
|
||||||
else
|
else
|
||||||
((struct my_option *)opt)->app_type = order++;
|
*app_type = order++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,22 +949,6 @@ end:
|
|||||||
|
|
||||||
template class Vector<struct my_option>;
|
template class Vector<struct my_option>;
|
||||||
|
|
||||||
#if 0
|
/*
|
||||||
struct my_option
|
See include/my_getopt.h for the declaration of struct my_option
|
||||||
{
|
*/
|
||||||
const char *name; /* Name of the option */
|
|
||||||
int id; /* unique id or short option */
|
|
||||||
const char *comment; /* option comment, for autom. --help */
|
|
||||||
gptr *value; /* The variable value */
|
|
||||||
gptr *u_max_value; /* The user def. max variable value */
|
|
||||||
const char **str_values; /* Pointer to possible values */
|
|
||||||
ulong var_type;
|
|
||||||
enum get_opt_arg_type arg_type;
|
|
||||||
longlong def_value; /* Default value */
|
|
||||||
longlong min_value; /* Min allowed value */
|
|
||||||
longlong max_value; /* Max allowed value */
|
|
||||||
longlong sub_size; /* Subtract this from given value */
|
|
||||||
long block_size; /* Value should be a mult. of this */
|
|
||||||
int app_type; /* To be used by an application */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user