231
231
static void plugin_vars_free_values(sys_var *vars);
232
232
static void plugin_opt_set_limits(struct my_option *options,
233
233
const struct st_mysql_sys_var *opt);
234
#define my_intern_plugin_lock(A,B) intern_plugin_lock(A,B)
235
#define my_intern_plugin_lock_ci(A,B) intern_plugin_lock(A,B)
236
234
static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin);
237
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
238
235
static void reap_plugins(void);
309
306
for (i= 0; i < plugin_dl_array.elements; i++)
311
308
tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
312
if (tmp->ref_count &&
313
! my_strnncoll(files_charset_info,
309
if (! my_strnncoll(files_charset_info,
314
310
(const unsigned char *)dl->str, dl->length,
315
311
(const unsigned char *)tmp->dl.str, tmp->dl.length))
454
447
struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
455
448
struct st_plugin_dl **);
456
if (tmp->ref_count &&
457
! my_strnncoll(files_charset_info,
449
if (! my_strnncoll(files_charset_info,
458
450
(const unsigned char *)dl->str, dl->length,
459
451
(const unsigned char *)tmp->dl.str, tmp->dl.length))
461
453
/* Do not remove this element, unless no other plugin uses this dll. */
462
if (! --tmp->ref_count)
464
455
free_plugin_mem(tmp);
465
456
memset(tmp, 0, sizeof(struct st_plugin_dl));
554
548
if ((plugin= registry.find(name, type)))
555
rc= my_intern_plugin_lock_ci(lex, plugin_int_to_ref(plugin));
549
rc= intern_plugin_lock(lex, plugin_int_to_ref(plugin));
560
554
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
563
556
struct st_plugin_int *tmp;
564
for (i= 0; i < plugin_array.elements; i++)
566
tmp= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
567
if (tmp->state == PLUGIN_IS_FREED)
569
memcpy(tmp, plugin, sizeof(struct st_plugin_int));
573
557
if (insert_dynamic(&plugin_array, (unsigned char*)&plugin))
575
559
tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
654
static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
638
static void plugin_deinitialize(struct st_plugin_int *plugin)
656
640
if (plugin->plugin->status_vars)
660
We have a problem right now where we can not prepend without
661
breaking backwards compatibility. We will fix this shortly so
662
that engines have "use names" and we wil use those for
663
CREATE TABLE, and use the plugin name then for adding automatic
667
{plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
670
remove_status_vars(array);
672
642
remove_status_vars(plugin->plugin->status_vars);
673
#endif /* FIX_LATER */
676
645
if (plugin_type_deinitialize[plugin->plugin->type])
685
654
plugin->plugin->deinit(plugin);
687
656
plugin->state= PLUGIN_IS_UNINITIALIZED;
690
We do the check here because NDB has a worker Session which doesn't
691
exit until NDB is shut down.
693
if (ref_check && plugin->ref_count)
694
errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has ref_count=%d after deinitialization."),
695
plugin->name.str, plugin->ref_count);
718
678
struct st_plugin_int *plugin;
721
680
count= plugin_array.elements;
723
682
for (idx= 0; idx < count; idx++)
725
684
plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
726
685
plugin->state= PLUGIN_IS_DYING;
727
plugin_deinitialize(plugin, true);
686
plugin_deinitialize(plugin);
728
687
plugin_del(plugin);
732
static void intern_plugin_unlock(LEX *, plugin_ref plugin)
739
pi= plugin_ref_to_int(plugin);
741
free((void *) plugin);
743
//assert(pi->ref_count);
744
if (pi->ref_count > 0)
747
if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count)
754
void plugin_unlock(Session *session, plugin_ref plugin)
756
LEX *lex= session ? session->lex : 0;
759
intern_plugin_unlock(lex, plugin);
764
void plugin_unlock_list(Session *session, plugin_ref *list, uint32_t count)
766
LEX *lex= session ? session->lex : 0;
769
intern_plugin_unlock(lex, *list++);
774
691
static int plugin_initialize(struct st_plugin_int *plugin)
776
693
plugin->state= PLUGIN_IS_UNINITIALIZED;
1081
997
reap_needed= true;
1084
We want to shut down plugins in a reasonable order, this will
1085
become important when we have plugins which depend upon each other.
1086
Circular references cannot be reaped so they are forced afterwards.
1087
TODO: Have an additional step here to notify all active plugins that
1088
shutdown is requested to allow plugins to deinitialize in parallel.
1090
while (reap_needed && (count= plugin_array.elements))
1093
for (idx= free_slots= 0; idx < count; idx++)
1095
plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1096
switch (plugin->state) {
1097
case PLUGIN_IS_READY:
1098
plugin->state= PLUGIN_IS_DELETED;
1101
case PLUGIN_IS_FREED:
1102
case PLUGIN_IS_UNINITIALIZED:
1110
release any plugin references held.
1112
unlock_variables(NULL, &global_system_variables);
1113
unlock_variables(NULL, &max_system_variables);
1117
if (count > free_slots)
1118
errmsg_printf(ERRMSG_LVL_WARN, _("Forcing shutdown of %"PRIu64" plugins"),
1119
(uint64_t)count - free_slots);
1121
plugins.reserve(count);
1124
If we have any plugins which did not die cleanly, we force shutdown
1126
for (idx= 0; idx < count; idx++)
1128
plugins.push_back(*dynamic_element(&plugin_array, idx,
1129
struct st_plugin_int **));
1130
/* change the state to ensure no reaping races */
1131
if (plugins[idx]->state == PLUGIN_IS_DELETED)
1132
plugins[idx]->state= PLUGIN_IS_DYING;
1136
We loop through all plugins and call deinit() if they have one.
1138
for (idx= 0; idx < count; idx++)
1139
if (!(plugins[idx]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1141
errmsg_printf(ERRMSG_LVL_INFO, _("Plugin '%s' will be forced to shutdown"),
1142
plugins[idx]->name.str);
1144
We are forcing deinit on plugins so we don't want to do a ref_count
1145
check until we have processed all the plugins.
1147
plugin_deinitialize(plugins[idx], false);
1151
We defer checking ref_counts until after all plugins are deinitialized
1152
as some may have worker threads holding on to plugin references.
1154
for (idx= 0; idx < count; idx++)
1156
if (plugins[idx]->ref_count)
1157
errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has ref_count=%d after shutdown."),
1158
plugins[idx]->name.str, plugins[idx]->ref_count);
1159
if (plugins[idx]->state & PLUGIN_IS_UNINITIALIZED)
1160
plugin_del(plugins[idx]);
1164
Now we can deallocate all memory.
1000
unlock_variables(NULL, &global_system_variables);
1001
unlock_variables(NULL, &max_system_variables);
1167
1003
cleanup_variables(NULL, &global_system_variables);
1168
1004
cleanup_variables(NULL, &max_system_variables);
1170
1006
initialized= 0;
1174
1009
/* Dispose of the memory */
1570
1403
pthread_rwlock_unlock(&LOCK_system_variables_hash);
1571
1404
LEX *lex= session ? session->lex : 0;
1572
if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
1405
if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
1573
1406
var= NULL; /* failed to lock it, it must be uninstalling */
1575
1408
if (!(plugin_state(plugin) & PLUGIN_IS_READY))
1577
/* initialization not completed */
1579
intern_plugin_unlock(lex, plugin);