summaryrefslogtreecommitdiff
path: root/sql/sql_repl.cc
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@oracle.com>2010-09-06 18:18:44 +0100
committerAlfranio Correia <alfranio.correia@oracle.com>2010-09-06 18:18:44 +0100
commiteab1def49ad1785ad65c9388de3704a5d658a0f6 (patch)
tree5a565d2cb4494feb616399f54d66ff3fdcb1e74a /sql/sql_repl.cc
parent744c1013a2b429557fec07246e812fcc40ec00a8 (diff)
parente297990d5b17cf888f6ac6d0c069551c317a53ef (diff)
downloadmariadb-git-eab1def49ad1785ad65c9388de3704a5d658a0f6.tar.gz
BUG#55415 wait_for_update_bin_log enters a condition but does not leave
In sql/log.c, member function wait_for_update_bin_log, a condition is entered with THD::enter_cond but is not exited. This might leave dangling references to the mutex/condition in the per-thread information area. To fix the problem, we call exit_cond to properly remove references to the mutex, LOCK_log.
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r--sql/sql_repl.cc16
1 files changed, 13 insertions, 3 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index ab6c6e738b2..7bca41f1265 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -448,6 +448,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
const char *errmsg = "Unknown error";
NET* net = &thd->net;
mysql_mutex_t *log_lock;
+ mysql_cond_t *log_cond;
+
bool binlog_can_be_corrupted= FALSE;
#ifndef DBUG_OFF
int left_events = max_binlog_dump_events;
@@ -591,7 +593,8 @@ impossible position";
mysql_bin_log, and it's already inited, and it will be destroyed
only at shutdown).
*/
- log_lock = mysql_bin_log.get_log_lock();
+ log_lock= mysql_bin_log.get_log_lock();
+ log_cond= mysql_bin_log.get_log_cond();
if (pos > BIN_LOG_HEADER_SIZE)
{
/* reset transmit packet for the event read from binary log
@@ -826,6 +829,7 @@ impossible position";
#ifndef DBUG_OFF
ulong hb_info_counter= 0;
#endif
+ const char* old_msg= thd->proc_info;
signal_cnt= mysql_bin_log.signal_cnt;
do
{
@@ -834,6 +838,9 @@ impossible position";
DBUG_ASSERT(heartbeat_ts && heartbeat_period != 0);
set_timespec_nsec(*heartbeat_ts, heartbeat_period);
}
+ thd->enter_cond(log_cond, log_lock,
+ "Master has sent all binlog to slave; "
+ "waiting for binlog to be updated");
ret= mysql_bin_log.wait_for_update_bin_log(thd, heartbeat_ts);
DBUG_ASSERT(ret == 0 || (heartbeat_period != 0 && coord != NULL));
if (ret == ETIMEDOUT || ret == ETIME)
@@ -849,12 +856,15 @@ impossible position";
#endif
/* reset transmit packet for the heartbeat event */
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg))
+ {
+ thd->exit_cond(old_msg);
goto err;
+ }
if (send_heartbeat_event(net, packet, coord))
{
errmsg = "Failed on my_net_write()";
my_errno= ER_UNKNOWN_ERROR;
- mysql_mutex_unlock(log_lock);
+ thd->exit_cond(old_msg);
goto err;
}
}
@@ -863,7 +873,7 @@ impossible position";
DBUG_PRINT("wait",("binary log received update or a broadcast signal caught"));
}
} while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed);
- mysql_mutex_unlock(log_lock);
+ thd->exit_cond(old_msg);
}
break;