diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-12-16 11:33:54 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-12-16 11:33:54 +0300 |
commit | 980e8b413e89175d8fc7f867415712589bead9ff (patch) | |
tree | 765dbf44bc16c28e3d63a3439bed89b86e4b92fc /sql/rpl_handler.cc | |
parent | d1dfce06b254548e108deabfe8a7e6b759984d5d (diff) | |
parent | 376cf4275f28f6b8167eaf19b2c66dee41fbc5c5 (diff) | |
download | mariadb-git-980e8b413e89175d8fc7f867415712589bead9ff.tar.gz |
Merge next-mr -> next-4284.
Diffstat (limited to 'sql/rpl_handler.cc')
-rw-r--r-- | sql/rpl_handler.cc | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index b8b82bc2f98..ebd6e4e0c0b 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -137,28 +137,53 @@ void delegates_destroy() */ #define FOREACH_OBSERVER(r, f, thd, args) \ param.server_id= thd->server_id; \ + /* + Use a struct to make sure that they are allocated adjacent, check + delete_dynamic(). + */ \ + struct { \ + DYNAMIC_ARRAY plugins; \ + /* preallocate 8 slots */ \ + plugin_ref plugins_buffer[8]; \ + } s; \ + DYNAMIC_ARRAY *plugins= &s.plugins; \ + plugin_ref *plugins_buffer= s.plugins_buffer; \ + my_init_dynamic_array2(plugins, sizeof(plugin_ref), \ + plugins_buffer, 8, 8); \ read_lock(); \ Observer_info_iterator iter= observer_info_iter(); \ Observer_info *info= iter++; \ for (; info; info= iter++) \ { \ plugin_ref plugin= \ - my_plugin_lock(thd, &info->plugin); \ + my_plugin_lock(0, &info->plugin); \ if (!plugin) \ { \ - r= 1; \ + /* plugin is not intialized or deleted, this is not an error */ \ + r= 0; \ break; \ } \ + insert_dynamic(plugins, (uchar *)&plugin); \ if (((Observer *)info->observer)->f \ && ((Observer *)info->observer)->f args) \ { \ r= 1; \ - plugin_unlock(thd, plugin); \ + sql_print_error("Run function '" #f "' in plugin '%s' failed", \ + info->plugin_int->name.str); \ break; \ } \ - plugin_unlock(thd, plugin); \ } \ - unlock() + unlock(); \ + /* + Unlock plugins should be done after we released the Delegate lock + to avoid possible deadlock when this is the last user of the + plugin, and when we unlock the plugin, it will try to + deinitialize the plugin, which will try to lock the Delegate in + order to remove the observers. + */ \ + plugin_unlock_list(0, (plugin_ref*)plugins->buffer, \ + plugins->elements); \ + delete_dynamic(plugins) int Trans_delegate::after_commit(THD *thd, bool all) |