summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorunknown <guilhem@mysql.com>2004-07-31 22:33:20 +0200
committerunknown <guilhem@mysql.com>2004-07-31 22:33:20 +0200
commit00e7ec42795c08da55a22cc76d1e988c2a114098 (patch)
tree0f8a3d06ad26a2e3d61d38def3d87f5c2097ccaa /sql/lock.cc
parent42ed0103c8cac51d84c9fdf339058a85667cd19a (diff)
downloadmariadb-git-00e7ec42795c08da55a22cc76d1e988c2a114098.tar.gz
Fix for:
Bug #4810 "deadlock with KILL when the victim was in a wait state" (I included mutex unlock into exit_cond() for future safety) and BUG#4827 "KILL while START SLAVE may lead to replication slave crash" sql/lock.cc: we did exit_cond() before unlock(LOCK_open), which led to deadlocks with THD::awake(). Fixing this. sql/log.cc: mutex unlock is now included in exit_cond() sql/repl_failsafe.cc: we did exit_cond() before unlock(LOCK_rpl_status), which led to deadlocks with THD::awake(). Fixing this. sql/slave.cc: we did exit_cond() before unlock(cond_lock), which led to deadlocks with THD::awake(). Fixing this. Fixing also that if killed while waiting for slave thread to start, we don't release the mutex (that caused a double release of the mutex => crash). sql/sql_class.h: comments about exit_cond()/enter_cond(). Mutex unlock is now included in exit_cond() so that it's always done in the good order. sql/sql_table.cc: unlock is now included in exit_cond().
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc16
1 files changed, 9 insertions, 7 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 5010d115a6c..9ea1ce96175 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -692,15 +692,14 @@ bool lock_global_read_lock(THD *thd)
while (protect_against_global_read_lock && !thd->killed)
pthread_cond_wait(&COND_refresh, &LOCK_open);
waiting_for_read_lock--;
- thd->exit_cond(old_message);
if (thd->killed)
{
- (void) pthread_mutex_unlock(&LOCK_open);
+ thd->exit_cond(old_message);
DBUG_RETURN(1);
}
thd->global_read_lock=1;
global_read_lock++;
- (void) pthread_mutex_unlock(&LOCK_open);
+ thd->exit_cond(old_message);
}
DBUG_RETURN(0);
}
@@ -721,11 +720,12 @@ void unlock_global_read_lock(THD *thd)
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
{
const char *old_message;
- bool result=0;
+ bool result= 0, need_exit_cond;
DBUG_ENTER("wait_if_global_read_lock");
+ LINT_INIT(old_message);
(void) pthread_mutex_lock(&LOCK_open);
- if (global_read_lock)
+ if (need_exit_cond= (bool)global_read_lock)
{
if (thd->global_read_lock) // This thread had the read locks
{
@@ -740,11 +740,13 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
if (thd->killed)
result=1;
- thd->exit_cond(old_message);
}
if (!abort_on_refresh && !result)
protect_against_global_read_lock++;
- pthread_mutex_unlock(&LOCK_open);
+ if (unlikely(need_exit_cond)) // global read locks are rare
+ thd->exit_cond(old_message);
+ else
+ pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(result);
}