719
720
static void reap_plugins(void)
722
struct st_plugin_int *plugin, **reap, **list;
724
struct st_plugin_int *plugin;
725
vector<st_plugin_int *> reap;
726
vector<st_plugin_int *>::reverse_iterator riter;
724
728
if (!reap_needed)
727
732
reap_needed= false;
728
733
count= plugin_array.elements;
729
reap= (struct st_plugin_int **)my_alloca(sizeof(plugin)*(count+1));
732
736
for (idx= 0; idx < count; idx++)
737
741
/* change the status flag to prevent reaping by another thread */
738
742
plugin->state= PLUGIN_IS_DYING;
743
reap.push_back(plugin);
744
while ((plugin= *(--list)))
747
for (riter= reap.rbegin(); plugin= *riter, riter != reap.rend(); riter++)
745
748
plugin_deinitialize(plugin, true);
747
while ((plugin= *(--reap)))
750
for (riter= reap.rbegin(); plugin= *riter, riter != reap.rend(); riter++)
748
751
plugin_del(plugin);
753
755
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
905
907
int plugin_init(int *argc, char **argv, int flags)
908
910
struct st_mysql_plugin **builtins;
909
911
struct st_mysql_plugin *plugin;
910
struct st_plugin_int tmp, *plugin_ptr, **reap;
912
struct st_plugin_int tmp, *plugin_ptr;
913
vector<st_plugin_int *> reap;
914
vector<st_plugin_int *>::reverse_iterator riter;
911
915
MEM_ROOT tmp_root;
927
931
sizeof(struct st_plugin_int *),16,16))
930
for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
934
for (idx= 0; idx < DRIZZLE_MAX_PLUGIN_TYPE_NUM; idx++)
932
if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0,
936
if (hash_init(&plugin_hash[idx], system_charset_info, 16, 0, 0,
933
937
get_plugin_hash_key, NULL, HASH_UNIQUE))
989
993
Now we initialize all remaining plugins
992
reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
995
for (i= 0; i < plugin_array.elements; i++)
995
reap.reserve(plugin_array.elements);
997
for (idx= 0; idx < plugin_array.elements; idx++)
997
plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
999
plugin_ptr= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
998
1000
if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
1000
1002
if (plugin_initialize(plugin_ptr))
1002
1004
plugin_ptr->state= PLUGIN_IS_DYING;
1003
*(reap++)= plugin_ptr;
1005
reap[idx]= plugin_ptr;
1009
1011
Check if any plugins have to be reaped
1011
while ((plugin_ptr= *(--reap)))
1013
for(riter= reap.rbegin();
1014
plugin_ptr= *riter, riter != reap.rend();
1013
1017
plugin_deinitialize(plugin_ptr, true);
1014
1018
plugin_del(plugin_ptr);
1020
1022
free_root(&tmp_root, MYF(0));
1136
1138
void plugin_shutdown(void)
1138
uint32_t i, count= plugin_array.elements, free_slots= 0;
1139
struct st_plugin_int **plugins, *plugin;
1140
struct st_plugin_dl **dl;
1140
uint32_t idx, free_slots= 0;
1141
size_t count= plugin_array.elements;
1142
struct st_plugin_int *plugin;
1143
vector<st_plugin_int *> plugins;
1144
vector<st_plugin_dl *> dl;
1142
1146
if (initialized)
1153
1157
while (reap_needed && (count= plugin_array.elements))
1155
1159
reap_plugins();
1156
for (i= free_slots= 0; i < count; i++)
1160
for (idx= free_slots= 0; idx < count; idx++)
1158
plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
1162
plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1159
1163
switch (plugin->state) {
1160
1164
case PLUGIN_IS_READY:
1161
1165
plugin->state= PLUGIN_IS_DELETED;
1180
1184
if (count > free_slots)
1181
sql_print_warning(_("Forcing shutdown of %d plugins"),
1182
count - free_slots);
1185
sql_print_warning(_("Forcing shutdown of %"PRIu64" plugins"),
1186
(uint64_t)count - free_slots);
1184
plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
1188
plugins.reserve(count);
1187
1191
If we have any plugins which did not die cleanly, we force shutdown
1189
for (i= 0; i < count; i++)
1193
for (idx= 0; idx < count; idx++)
1191
plugins[i]= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
1195
plugins.push_back(*dynamic_element(&plugin_array, idx,
1196
struct st_plugin_int **));
1192
1197
/* change the state to ensure no reaping races */
1193
if (plugins[i]->state == PLUGIN_IS_DELETED)
1194
plugins[i]->state= PLUGIN_IS_DYING;
1198
if (plugins[idx]->state == PLUGIN_IS_DELETED)
1199
plugins[idx]->state= PLUGIN_IS_DYING;
1198
1203
We loop through all plugins and call deinit() if they have one.
1200
for (i= 0; i < count; i++)
1201
if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1205
for (idx= 0; idx < count; idx++)
1206
if (!(plugins[idx]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1203
1208
sql_print_information(_("Plugin '%s' will be forced to shutdown"),
1204
plugins[i]->name.str);
1209
plugins[idx]->name.str);
1206
1211
We are forcing deinit on plugins so we don't want to do a ref_count
1207
1212
check until we have processed all the plugins.
1209
plugin_deinitialize(plugins[i], false);
1214
plugin_deinitialize(plugins[idx], false);
1213
1218
We defer checking ref_counts until after all plugins are deinitialized
1214
1219
as some may have worker threads holding on to plugin references.
1216
for (i= 0; i < count; i++)
1221
for (idx= 0; idx < count; idx++)
1218
if (plugins[i]->ref_count)
1223
if (plugins[idx]->ref_count)
1219
1224
sql_print_error(_("Plugin '%s' has ref_count=%d after shutdown."),
1220
plugins[i]->name.str, plugins[i]->ref_count);
1221
if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
1222
plugin_del(plugins[i]);
1225
plugins[idx]->name.str, plugins[idx]->ref_count);
1226
if (plugins[idx]->state & PLUGIN_IS_UNINITIALIZED)
1227
plugin_del(plugins[idx]);
1232
1237
initialized= 0;
1237
1241
/* Dispose of the memory */
1239
for (i= 0; i < DRIZZLE_MAX_PLUGIN_TYPE_NUM; i++)
1240
hash_free(&plugin_hash[i]);
1243
for (idx= 0; idx < DRIZZLE_MAX_PLUGIN_TYPE_NUM; idx++)
1244
hash_free(&plugin_hash[idx]);
1241
1245
delete_dynamic(&plugin_array);
1243
1247
count= plugin_dl_array.elements;
1244
dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count);
1245
for (i= 0; i < count; i++)
1246
dl[i]= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
1247
for (i= 0; i < plugin_dl_array.elements; i++)
1248
free_plugin_mem(dl[i]);
1249
for (idx= 0; idx < count; idx++)
1250
dl.push_back(*dynamic_element(&plugin_dl_array, idx,
1251
struct st_plugin_dl **));
1252
for (idx= 0; idx < count; idx++)
1253
free_plugin_mem(dl[idx]);
1250
1254
delete_dynamic(&plugin_dl_array);
1252
1256
hash_free(&bookmark_hash);
1261
1265
bool plugin_foreach_with_mask(Session *session, plugin_foreach_func *func,
1262
1266
int type, uint32_t state_mask, void *arg)
1264
uint32_t idx, total;
1265
struct st_plugin_int *plugin, **plugins;
1270
struct st_plugin_int *plugin;
1271
vector<st_plugin_int *> plugins;
1266
1272
int version=plugin_array_version;
1268
1274
if (!initialized)
1273
1279
total= type == DRIZZLE_ANY_PLUGIN ? plugin_array.elements
1274
1280
: plugin_hash[type].records;
1276
Do the alloca out here in case we do have a working alloca:
1277
leaving the nested stack frame invalidates alloca allocation.
1279
plugins=(struct st_plugin_int **)my_alloca(total*sizeof(plugin));
1281
plugins.reserve(total);
1280
1283
if (type == DRIZZLE_ANY_PLUGIN)
1282
1285
for (idx= 0; idx < total; idx++)
1284
1287
plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1285
plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
1288
plugins.push_back(!(plugin->state & state_mask) ? plugin : NULL);
1291
1294
for (idx= 0; idx < total; idx++)
1293
1296
plugin= (struct st_plugin_int *) hash_element(hash, idx);
1294
plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
1297
plugins.push_back(!(plugin->state & state_mask) ? plugin : NULL);
1297
1300
for (idx= 0; idx < total; idx++)
1730
varname= ((char*) my_alloca(length));
1731
varname= ((char*) malloc(length));
1731
1732
strxmov(varname + 1, plugin, "_", name, NULL);
1732
1733
for (p= varname + 1; *p; p++)