summaryrefslogtreecommitdiff
path: root/sql/rpl_handler.cc
diff options
context:
space:
mode:
authorHe Zhenxing <zhenxing.he@sun.com>2009-12-04 16:05:35 +0800
committerHe Zhenxing <zhenxing.he@sun.com>2009-12-04 16:05:35 +0800
commite35e781680134ce42c8d1a628808b097d555c5b1 (patch)
treec454a92d737001fe2c4210875a93869d2bee519c /sql/rpl_handler.cc
parent055030457ef4de25f7807ca96c48ef5378748cb7 (diff)
parent30d2870a9c0999c615a07f93194e6d8b20e5d9d6 (diff)
downloadmariadb-git-e35e781680134ce42c8d1a628808b097d555c5b1.tar.gz
Auto merge fixes for Bug#49020
Diffstat (limited to 'sql/rpl_handler.cc')
-rw-r--r--sql/rpl_handler.cc35
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)