From 2f8849e2aafc9f95390024f35572dc015d35e38a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Aug 2006 11:58:12 -0700 Subject: [PATCH 1/5] Re'ordering of startup. Fixed Execution path issues. Added function for de'initing everything. This includes Antony's suggestions (bk collapse uber alles!) sql/handler.cc: Removed temp work needed for making status variables work with plugins. sql/mysqld.cc: Removed call to plugin_load() (not needed any longer). sql/sql_plugin.cc: Status vars are now located in only one location (while this fixed execution path problems, we will need to now fix "the name" issues). Monty and I have a solution to this :) Added function for deiniting engines (before the logic was scattered about). Added step by step processing for startup of plugins. MyISAM is now loaded first (we will address this long term in a different manner). sql/sql_plugin.h: Removed calls that did not need to be extern. --- sql/handler.cc | 6 -- sql/mysqld.cc | 7 +- sql/sql_plugin.cc | 196 +++++++++++++++++++++++++--------------------- sql/sql_plugin.h | 7 +- 4 files changed, 112 insertions(+), 104 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index dd1be47e3c2..465919d49a8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -430,12 +430,6 @@ int ha_initialize_handlerton(st_plugin_int *plugin) savepoint_alloc_size+= tmp; hton->slot= total_ha++; hton2plugin[hton->slot]=plugin; - /* This is just a temp need until plugin/engine startup is fixed */ - if (plugin->plugin->status_vars) - { - add_status_vars(plugin->plugin->status_vars); - } - if (hton->prepare) total_ha_2pc++; break; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 46f5e0ae4e9..9b2f61ee2cf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1186,7 +1186,7 @@ void clean_up(bool print_message) udf_free(); #endif } - plugin_free(); + plugin_shutdown(); if (tc_log) tc_log->close(); xid_cache_free(); @@ -2629,7 +2629,7 @@ static int init_common_variables(const char *conf_file_name, int argc, /* Add server status variables to the dynamic list of status variables that is shown by SHOW STATUS. - Later, in plugin_init, plugin_load, and mysql_install_plugin + Later, in plugin_init, and mysql_install_plugin new entries could be added to that list. */ if (add_status_vars(status_vars)) @@ -3178,7 +3178,7 @@ server."); using_update_log=1; } - if (plugin_init()) + if (plugin_init(0)) { sql_print_error("Failed to init plugins."); return 1; @@ -3610,7 +3610,6 @@ we force server id to 2, but this MySQL server will not act as a slave."); if (!opt_noacl) { - plugin_load(); #ifdef HAVE_DLOPEN udf_init(); #endif diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 074999a52cf..9db7c743a40 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -63,6 +63,10 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; static rw_lock_t THR_LOCK_plugin; static bool initialized= 0; +/* prototypes */ +my_bool plugin_register_builtin(struct st_mysql_plugin *plugin); +void plugin_load(void); + static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl) { uint i; @@ -442,15 +446,6 @@ static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int repo tmp.name.length= name_len; tmp.ref_count= 0; tmp.state= PLUGIN_IS_UNINITIALIZED; - if (plugin->status_vars) - { - SHOW_VAR array[2]= { - {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY}, - {0, 0, SHOW_UNDEF} - }; - if (add_status_vars(array)) // add_status_vars makes a copy - goto err; - } if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp))) goto err; if (my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr)) @@ -466,19 +461,38 @@ static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int repo if (report & REPORT_TO_LOG) sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str); err: - if (plugin->status_vars) - { - SHOW_VAR array[2]= { - {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY}, - {0, 0, SHOW_UNDEF} - }; - remove_status_vars(array); - } plugin_dl_del(dl); DBUG_RETURN(TRUE); } +void plugin_deinitializer(struct st_plugin_int *plugin) +{ + if (plugin->plugin->status_vars) + { + SHOW_VAR array[2]= { + {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, + {0, 0, SHOW_UNDEF} + }; + remove_status_vars(array); + } + + if (plugin->state == PLUGIN_IS_READY) + { + if (plugin->plugin->deinit) + { + DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str)); + if (plugin->plugin->deinit()) + { + DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", + plugin->name.str)); + } + } + plugin->state= PLUGIN_IS_UNINITIALIZED; + } +} + + static void plugin_del(const LEX_STRING *name) { uint i; @@ -486,14 +500,7 @@ static void plugin_del(const LEX_STRING *name) DBUG_ENTER("plugin_del"); if ((plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN))) { - if (plugin->plugin->status_vars) - { - SHOW_VAR array[2]= { - {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, - {0, 0, SHOW_UNDEF} - }; - remove_status_vars(array); - } + plugin_deinitializer(plugin); hash_delete(&plugin_hash[plugin->plugin->type], (byte*)plugin); plugin_dl_del(&plugin->plugin_dl->dl); plugin->state= PLUGIN_IS_FREED; @@ -523,6 +530,26 @@ static int plugin_initialize(struct st_plugin_int *plugin) { DBUG_ENTER("plugin_initialize"); + if (plugin->plugin->status_vars) + { +#ifdef FIX_LATER + /* + We have a problem right now where we can not prepend without + breaking backwards compatibility. We will fix this shortly so + that engines have "use names" and we wil use those for + CREATE TABLE, and use the plugin name then for adding automatic + variable names. + */ + SHOW_VAR array[2]= { + {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY}, + {0, 0, SHOW_UNDEF} + }; + if (add_status_vars(array)) // add_status_vars makes a copy + goto err; +#else + add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy +#endif /* FIX_LATER */ + } if (plugin->plugin->init) { if (plugin->plugin->init()) @@ -540,6 +567,8 @@ static int plugin_initialize(struct st_plugin_int *plugin) goto err; } + plugin->state= PLUGIN_IS_READY; + DBUG_RETURN(0); err: DBUG_RETURN(1); @@ -592,52 +621,6 @@ err: DBUG_RETURN(1); } -static void plugin_call_initializer(void) -{ - uint i; - DBUG_ENTER("plugin_call_initializer"); - for (i= 0; i < plugin_array.elements; i++) - { - struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, - struct st_plugin_int *); - if (tmp->state == PLUGIN_IS_UNINITIALIZED) - { - if (plugin_initialize(tmp)) - plugin_del(&tmp->name); - else - tmp->state= PLUGIN_IS_READY; - } - } - DBUG_VOID_RETURN; -} - - -static void plugin_call_deinitializer(void) -{ - uint i; - DBUG_ENTER("plugin_call_deinitializer"); - for (i= 0; i < plugin_array.elements; i++) - { - struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, - struct st_plugin_int *); - if (tmp->state == PLUGIN_IS_READY) - { - if (tmp->plugin->deinit) - { - DBUG_PRINT("info", ("Deinitializing plugin: '%s'", tmp->name.str)); - if (tmp->plugin->deinit()) - { - DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", - tmp->name.str)); - } - } - tmp->state= PLUGIN_IS_UNINITIALIZED; - } - } - DBUG_VOID_RETURN; -} - - static byte *get_hash_key(const byte *buff, uint *length, my_bool not_used __attribute__((unused))) { @@ -647,7 +630,14 @@ static byte *get_hash_key(const byte *buff, uint *length, } -int plugin_init(void) +/* + The logic is that we first load and initialize all compiled in plugins. + From there we load up the dynamic types (assuming we have not been told to + skip this part). + + Finally we inializie everything, aka the dynamic that have yet to initialize. +*/ +int plugin_init(int skip_dynamic_loading) { int i; struct st_mysql_plugin **builtins; @@ -672,24 +662,46 @@ int plugin_init(void) goto err; } - /* Register all the built-in plugins */ + /* + First we register builtin plugins + */ for (builtins= mysqld_builtins; *builtins; builtins++) { for (plugin= *builtins; plugin->info; plugin++) { - if (plugin_register_builtin(plugin)) - goto err; - struct st_plugin_int *tmp=dynamic_element(&plugin_array, - plugin_array.elements-1, - struct st_plugin_int *); - if (plugin_initialize(tmp)) - goto err; - tmp->state= PLUGIN_IS_READY; +// if (!(strcmp(plugin->name, "MyISAM"))) + { + if (plugin_register_builtin(plugin)) + goto err; + struct st_plugin_int *tmp= dynamic_element(&plugin_array, + plugin_array.elements-1, + struct st_plugin_int *); + if (plugin_initialize(tmp)) + goto err; + } } } + /* Register all dynamic plugins */ + if (!skip_dynamic_loading) + plugin_load(); + initialized= 1; + /* + Now we initialize all remaining plugins + */ + for (i= 0; i < plugin_array.elements; i++) + { + struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, + struct st_plugin_int *); + if (tmp->state == PLUGIN_IS_UNINITIALIZED) + { + if (plugin_initialize(tmp)) + plugin_del(&tmp->name); + } + } + DBUG_RETURN(0); err: @@ -734,8 +746,6 @@ void plugin_load(void) THD *new_thd; DBUG_ENTER("plugin_load"); - DBUG_ASSERT(initialized); - if (!(new_thd= new THD)) { sql_print_error("Can't allocate memory for plugin structures"); @@ -772,7 +782,6 @@ void plugin_load(void) DBUG_PRINT("warning", ("Couldn't load plugin named '%s' with soname '%s'.", name.str, dl.str)); } - plugin_call_initializer(); if (error > 0) sql_print_error(ER(ER_GET_ERRNO), my_errno); end_read_record(&read_record_info); @@ -787,11 +796,22 @@ end: } -void plugin_free(void) +void plugin_shutdown(void) { uint i; - DBUG_ENTER("plugin_free"); - plugin_call_deinitializer(); + DBUG_ENTER("plugin_shutdown"); + + /* + We loop through all plugins and call deinit() if they have one. + */ + for (i= 0; i < plugin_array.elements; i++) + { + struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, + struct st_plugin_int *); + plugin_deinitializer(tmp); + + } + for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) hash_free(&plugin_hash[i]); delete_dynamic(&plugin_array); @@ -841,8 +861,6 @@ my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING goto err; } - tmp->state= PLUGIN_IS_READY; - table->use_all_columns(); restore_record(table, s->default_values); table->field[0]->store(name->str, name->length, system_charset_info); diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index df7c9a39495..ed7ba36ac84 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -67,17 +67,14 @@ typedef int (*plugin_type_init)(struct st_plugin_int *); extern char *opt_plugin_dir_ptr; extern char opt_plugin_dir[FN_REFLEN]; extern const LEX_STRING plugin_type_names[]; -extern int plugin_init(void); -extern void plugin_load(void); -extern void plugin_free(void); +extern int plugin_init(int); +extern void plugin_shutdown(void); extern my_bool plugin_is_ready(const LEX_STRING *name, int type); extern st_plugin_int *plugin_lock(const LEX_STRING *name, int type); extern void plugin_unlock(struct st_plugin_int *plugin); extern my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl); extern my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name); -extern my_bool plugin_register_builtin(struct st_mysql_plugin *plugin); - typedef my_bool (plugin_foreach_func)(THD *thd, st_plugin_int *plugin, void *arg); From d7de5c349b1f452d4d80b0fe99027e815360ecc9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Aug 2006 12:28:25 -0700 Subject: [PATCH 2/5] This pulls two function calls which should have been handlerton calls out of handler.cc. sql/ha_ndbcluster.cc: Adding in new handlerton calls. sql/handler.cc: Calls directly made to NDB have been removed. sql/handler.h: Two additional handlerton structure functions. --- sql/ha_ndbcluster.cc | 2 ++ sql/handler.cc | 64 +++++++++++++++++++++++++++++++++++--------- sql/handler.h | 6 ++++- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c7b0ce95214..486bbd35fc0 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6388,6 +6388,8 @@ static int ndbcluster_init() #endif h.flags= HTON_CAN_RECREATE | HTON_TEMPORARY_NOT_SUPPORTED; h.discover= ndbcluster_discover; + h.find_files= ndbcluster_find_files; + h.table_exists_in_engine= ndbcluster_table_exists_in_engine; } if (have_ndbcluster != SHOW_OPTION_YES) diff --git a/sql/handler.cc b/sql/handler.cc index 465919d49a8..9aaad7b3914 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -28,11 +28,6 @@ #include #include -#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE -#define NDB_MAX_ATTRIBUTES_IN_TABLE 128 -#include "ha_ndbcluster.h" -#endif - #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" #endif @@ -2745,6 +2740,29 @@ int ha_discover(THD *thd, const char *db, const char *name, to ask engine if there are any new tables that should be written to disk or any dropped tables that need to be removed from disk */ +typedef struct st_find_files_args +{ + const char *db; + const char *path; + const char *wild; + bool dir; + List *files; +}; + +static my_bool find_files_handlerton(THD *thd, st_plugin_int *plugin, + void *arg) +{ + st_find_files_args *vargs= (st_find_files_args *)arg; + handlerton *hton= (handlerton *)plugin->data; + + + if (hton->state == SHOW_OPTION_YES && hton->find_files) + if (hton->find_files(thd, vargs->db, vargs->path, vargs->wild, + vargs->dir, vargs->files)) + return TRUE; + + return FALSE; +} int ha_find_files(THD *thd,const char *db,const char *path, @@ -2754,10 +2772,11 @@ ha_find_files(THD *thd,const char *db,const char *path, DBUG_ENTER("ha_find_files"); DBUG_PRINT("enter", ("db: %s, path: %s, wild: %s, dir: %d", db, path, wild, dir)); -#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE - if (have_ndbcluster == SHOW_OPTION_YES) - error= ndbcluster_find_files(thd, db, path, wild, dir, files); -#endif + st_find_files_args args= {db, path, wild, dir, files}; + + plugin_foreach(thd, find_files_handlerton, + MYSQL_STORAGE_ENGINE_PLUGIN, &args); + /* The return value is not currently used */ DBUG_RETURN(error); } @@ -2771,15 +2790,34 @@ ha_find_files(THD *thd,const char *db,const char *path, # Error code */ + +typedef struct st_table_exists_in_engine_args +{ + const char *db; + const char *name; +}; + +static my_bool table_exists_in_engine_handlerton(THD *thd, st_plugin_int *plugin, + void *arg) +{ + st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg; + handlerton *hton= (handlerton *)plugin->data; + + if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine) + if ((hton->table_exists_in_engine(thd, vargs->db, vargs->name)) == 1) + return TRUE; + + return FALSE; +} + int ha_table_exists_in_engine(THD* thd, const char* db, const char* name) { int error= 0; DBUG_ENTER("ha_table_exists_in_engine"); DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); -#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE - if (have_ndbcluster == SHOW_OPTION_YES) - error= ndbcluster_table_exists_in_engine(thd, db, name); -#endif + st_table_exists_in_engine_args args= {db, name}; + error= plugin_foreach(thd, table_exists_in_engine_handlerton, + MYSQL_STORAGE_ENGINE_PLUGIN, &args); DBUG_PRINT("exit", ("error: %d", error)); DBUG_RETURN(error); } diff --git a/sql/handler.h b/sql/handler.h index bfc502b0658..f41cf1d6727 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -668,7 +668,11 @@ struct handlerton (*create_iterator)(enum handler_iterator_type type, struct handler_iterator *fill_this_in); int (*discover)(THD* thd, const char *db, const char *name, - const void** frmblob, uint* frmlen); + const void** frmblob, uint* frmlen); + int (*find_files)(THD *thd,const char *db,const char *path, + const char *wild, bool dir, List *files); + int (*table_exists_in_engine)(THD* thd, const char *db, + const char *name); }; From 2dfaa6697c9292d5777e6e2322d883d5c0f81936 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Aug 2006 14:27:29 -0700 Subject: [PATCH 3/5] add 2 placeholder values for config and system variables. --- include/mysql/plugin.h | 4 +++- plugin/fulltext/plugin_example.c | 4 +++- sql/ha_innodb.cc | 4 +++- sql/ha_ndbcluster.cc | 4 +++- sql/ha_partition.cc | 4 +++- sql/log.cc | 4 +++- storage/archive/ha_archive.cc | 4 +++- storage/blackhole/ha_blackhole.cc | 4 +++- storage/csv/ha_tina.cc | 4 +++- storage/example/ha_example.cc | 4 +++- storage/federated/ha_federated.cc | 4 +++- storage/heap/ha_heap.cc | 4 +++- storage/myisam/ha_myisam.cc | 4 +++- storage/myisammrg/ha_myisammrg.cc | 4 +++- 14 files changed, 42 insertions(+), 14 deletions(-) diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 156c3312c53..739f7bc5fc6 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -60,7 +60,7 @@ __MYSQL_DECLARE_PLUGIN(NAME, \ builtin_ ## NAME ## _sizeof_struct_st_plugin, \ builtin_ ## NAME ## _plugin) -#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0}} +#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0}} /* declarations for SHOW STATUS support in plugins @@ -96,6 +96,8 @@ struct st_mysql_plugin int (*deinit)(void); /* the function to invoke when plugin is unloaded */ unsigned int version; /* plugin version (for SHOW PLUGINS) */ struct st_mysql_show_var *status_vars; + void * __reserved1; /* placeholder for system variables */ + void * __reserved2; /* placeholder for config options */ }; /************************************************************************* diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c index beb02128774..34350e317ba 100644 --- a/plugin/fulltext/plugin_example.c +++ b/plugin/fulltext/plugin_example.c @@ -225,7 +225,9 @@ mysql_declare_plugin(ftexample) simple_parser_plugin_init, /* init function (when loaded) */ simple_parser_plugin_deinit,/* deinit function (when unloaded) */ 0x0001, /* version */ - simple_status /* status variables */ + simple_status, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 7f4d6abd4b7..9f7965ffb3a 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -7623,7 +7623,9 @@ mysql_declare_plugin(innobase) innobase_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, - innodb_status_variables_export + innodb_status_variables_export,/* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 486bbd35fc0..cc5e5b5040a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -10598,7 +10598,9 @@ mysql_declare_plugin(ndbcluster) ndbcluster_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, - ndb_status_variables_export + ndb_status_variables_export,/* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index ee0667b92bd..43303bb1a03 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5598,7 +5598,9 @@ mysql_declare_plugin(partition) partition_initialize, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100, /* 1.0 */ - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/sql/log.cc b/sql/log.cc index b93d36cf630..50b9119f7e6 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4678,6 +4678,8 @@ mysql_declare_plugin(binlog) binlog_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index de8b50fd2f3..3029b1db53e 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1583,7 +1583,9 @@ mysql_declare_plugin(archive) archive_db_init, /* Plugin Init */ archive_db_done, /* Plugin Deinit */ 0x0100 /* 1.0 */, - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index d22d9372e0d..c1141cce5ae 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -223,6 +223,8 @@ mysql_declare_plugin(blackhole) blackhole_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 2fe2afeb470..ce19202d745 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -1529,7 +1529,9 @@ mysql_declare_plugin(csv) tina_init_func, /* Plugin Init */ tina_done_func, /* Plugin Deinit */ 0x0100 /* 1.0 */, - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 704ea757749..6986796cb2e 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -715,7 +715,9 @@ mysql_declare_plugin(example) example_init_func, /* Plugin Init */ example_done_func, /* Plugin Deinit */ 0x0001 /* 0.1 */, - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 98f48b09ba6..456b6c73f3c 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -2896,7 +2896,9 @@ mysql_declare_plugin(federated) federated_db_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100 /* 1.0 */, - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 317f85d26f2..57777410bea 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -708,6 +708,8 @@ mysql_declare_plugin(heap) heap_init, NULL, 0x0100, /* 1.0 */ - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 209478ee9a5..6a32ba95eee 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1800,7 +1800,9 @@ mysql_declare_plugin(myisam) myisam_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100, /* 1.0 */ - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 8c767e32b83..2d1628e5e4f 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -573,6 +573,8 @@ mysql_declare_plugin(myisammrg) myisammrg_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0100, /* 1.0 */ - 0 + NULL, /* status variables */ + NULL, /* system variables */ + NULL /* config options */ } mysql_declare_plugin_end; From 6e5c98ea76590dc6e7e4d93c363f8ed336346040 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Sep 2006 23:59:16 +0200 Subject: [PATCH 4/5] plugin_foreach - don't hold the lock when calling the function --- sql/sql_plugin.cc | 58 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 9db7c743a40..8ed16d8af58 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -63,6 +63,8 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; static rw_lock_t THR_LOCK_plugin; static bool initialized= 0; +static int plugin_array_version=0; + /* prototypes */ my_bool plugin_register_builtin(struct st_mysql_plugin *plugin); void plugin_load(void); @@ -448,6 +450,7 @@ static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int repo tmp.state= PLUGIN_IS_UNINITIALIZED; if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp))) goto err; + plugin_array_version++; if (my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr)) { tmp_plugin_ptr->state= PLUGIN_IS_FREED; @@ -504,6 +507,7 @@ static void plugin_del(const LEX_STRING *name) hash_delete(&plugin_hash[plugin->plugin->type], (byte*)plugin); plugin_dl_del(&plugin->plugin_dl->dl); plugin->state= PLUGIN_IS_FREED; + plugin_array_version++; } DBUG_VOID_RETURN; } @@ -639,7 +643,7 @@ static byte *get_hash_key(const byte *buff, uint *length, */ int plugin_init(int skip_dynamic_loading) { - int i; + uint i; struct st_mysql_plugin **builtins; struct st_mysql_plugin *plugin; DBUG_ENTER("plugin_init"); @@ -939,43 +943,61 @@ err: DBUG_RETURN(TRUE); } - my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, int type, void *arg) { - uint idx; - struct st_plugin_int *plugin; + uint idx, total; + struct st_plugin_int *plugin, **plugins; + int version=plugin_array_version; DBUG_ENTER("plugin_foreach"); - rw_rdlock(&THR_LOCK_plugin); + rw_rdlock(&THR_LOCK_plugin); if (type == MYSQL_ANY_PLUGIN) { - for (idx= 0; idx < plugin_array.elements; idx++) + total=plugin_array.elements; + plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); + for (idx= 0; idx < total; idx++) { plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); - - /* FREED records may have garbage pointers */ - if ((plugin->state != PLUGIN_IS_FREED) && - func(thd, plugin, arg)) - goto err; + if (plugin->state == PLUGIN_IS_FREED) + continue; + plugins[idx]= plugin; } } else { HASH *hash= &plugin_hash[type]; - for (idx= 0; idx < hash->records; idx++) + total=hash->records; + plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); + for (idx= 0; idx < total; idx++) { plugin= (struct st_plugin_int *) hash_element(hash, idx); - if ((plugin->state != PLUGIN_IS_FREED) && - (plugin->state != PLUGIN_IS_DELETED) && - func(thd, plugin, arg)) - goto err; + if (plugin->state == PLUGIN_IS_FREED) + continue; + plugins[idx]= plugin; } } - rw_unlock(&THR_LOCK_plugin); + + for (idx= 0; idx < total; idx++) + { + plugin= plugins[idx]; + if (unlikely(version != plugin_array_version)) + { + rw_rdlock(&THR_LOCK_plugin); + for (uint i=idx; i < total; i++) + if (plugins[i]->state == PLUGIN_IS_FREED) + plugins[i]=0; + rw_unlock(&THR_LOCK_plugin); + } + if (plugin && func(thd, plugin, arg)) + goto err; + } + + my_afree(plugins); DBUG_RETURN(FALSE); err: - rw_unlock(&THR_LOCK_plugin); + my_afree(plugins); DBUG_RETURN(TRUE); } + From 71681467ca582a459c624832e367f2b91ee3e05c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Sep 2006 10:22:59 +0200 Subject: [PATCH 5/5] converting plugin states to bitmask to simplify testing. state_mask argument to plugin_foreach() sql/sql_show.cc: state_mask argument to plugin_foreach() --- sql/sql_plugin.cc | 16 +++++++++------- sql/sql_plugin.h | 25 +++++++++++++++---------- sql/sql_show.cc | 5 +++-- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8ed16d8af58..b66d2d20925 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -372,7 +372,7 @@ struct st_plugin_int *plugin_lock(const LEX_STRING *name, int type) rw_wrlock(&THR_LOCK_plugin); if ((rc= plugin_find_internal(name, type))) { - if (rc->state == PLUGIN_IS_READY || rc->state == PLUGIN_IS_UNINITIALIZED) + if (rc->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED)) rc->ref_count++; else rc= 0; @@ -943,13 +943,15 @@ err: DBUG_RETURN(TRUE); } -my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, - int type, void *arg) +my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, + int type, uint state_mask, void *arg) { uint idx, total; struct st_plugin_int *plugin, **plugins; int version=plugin_array_version; - DBUG_ENTER("plugin_foreach"); + DBUG_ENTER("plugin_foreach_with_mask"); + + state_mask= ~state_mask; // do it only once rw_rdlock(&THR_LOCK_plugin); if (type == MYSQL_ANY_PLUGIN) @@ -959,7 +961,7 @@ my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, for (idx= 0; idx < total; idx++) { plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); - if (plugin->state == PLUGIN_IS_FREED) + if (plugin->state & state_mask) continue; plugins[idx]= plugin; } @@ -972,7 +974,7 @@ my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, for (idx= 0; idx < total; idx++) { plugin= (struct st_plugin_int *) hash_element(hash, idx); - if (plugin->state == PLUGIN_IS_FREED) + if (plugin->state & state_mask) continue; plugins[idx]= plugin; } @@ -986,7 +988,7 @@ my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, { rw_rdlock(&THR_LOCK_plugin); for (uint i=idx; i < total; i++) - if (plugins[i]->state == PLUGIN_IS_FREED) + if (plugins[i]->state & state_mask) plugins[i]=0; rw_unlock(&THR_LOCK_plugin); } diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index ed7ba36ac84..fa3440f7f68 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -31,13 +31,17 @@ typedef struct st_mysql_show_var SHOW_VAR; #define MYSQL_ANY_PLUGIN -1 -enum enum_plugin_state -{ - PLUGIN_IS_FREED= 0, - PLUGIN_IS_DELETED, - PLUGIN_IS_UNINITIALIZED, - PLUGIN_IS_READY -}; +/* + different values of st_plugin_int::state + though they look like a bitmap, plugin may only + be in one of those eigenstates, not in a superposition of them :) + It's a bitmap, because it makes it easier to test + "whether the state is one of those..." +*/ +#define PLUGIN_IS_FREED 1 +#define PLUGIN_IS_DELETED 2 +#define PLUGIN_IS_UNINITIALIZED 4 +#define PLUGIN_IS_READY 8 /* A handle for the dynamic library containing a plugin or plugins. */ @@ -57,7 +61,7 @@ struct st_plugin_int LEX_STRING name; struct st_mysql_plugin *plugin; struct st_plugin_dl *plugin_dl; - enum enum_plugin_state state; + uint state; uint ref_count; /* number of threads using the plugin */ void *data; /* plugin type specific, e.g. handlerton */ }; @@ -78,6 +82,7 @@ extern my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name); typedef my_bool (plugin_foreach_func)(THD *thd, st_plugin_int *plugin, void *arg); -extern my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, - int type, void *arg); +#define plugin_foreach(A,B,C,D) plugin_foreach_with_mask(A,B,C,PLUGIN_IS_READY,D) +extern my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, + int type, uint state_mask, void *arg); #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a8bf2695ac4..3acc025b84f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -220,9 +220,10 @@ int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_ENTER("fill_plugins"); TABLE *table= tables->table; - if (plugin_foreach(thd, show_plugins, MYSQL_ANY_PLUGIN, table)) + if (plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN, + ~PLUGIN_IS_FREED, table)) DBUG_RETURN(1); - + DBUG_RETURN(0); }