summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2006-05-24 17:21:35 +0300
committerunknown <monty@mysql.com>2006-05-24 17:21:35 +0300
commit15a41be4b42aec2c3f68bc2ed9bae61d115d848a (patch)
treede08b2368707f34d1f5cded161308c6e5cc22730 /sql/lock.cc
parent57f138f7c9792b67e7b17b568b1a4cfcf2723760 (diff)
downloadmariadb-git-15a41be4b42aec2c3f68bc2ed9bae61d115d848a.tar.gz
More DBUG statements
Replaced COND_refresh with COND_global_read_lock becasue of a bug in NTPL threads when using different mutexes as arguments to pthread_cond_wait() The original code caused a hang in FLUSH TABLES WITH READ LOCK in some circumstances because pthread_cond_broadcast() was not delivered to other threads. This fixes: Bug#16986: Deadlock condition with MyISAM tables Bug#20048: FLUSH TABLES WITH READ LOCK causes a deadlock mysql-test/r/flush.result: Added test case for deadlock with FLUSH TABLES WITH READ LOCK mysql-test/r/lock_multi.result: Test for bug in LOCK TABLE + optimize table mysql-test/t/flush.test: Added test case for deadlock with FLUSH TABLES WITH READ LOCK mysql-test/t/lock_multi.test: Test for bug in LOCK TABLE + optimize table sql/lock.cc: Replaced COND_refresh with COND_global_read_lock becasue of a bug in NTPL threads when using different mutexes as arguments to pthread_cond_wait() The original code caused a hang in FLUSH TABLES WITH READ LOCK in some circumstances because pthread_cond_broadcast() was not delivered to other threads sql/mysql_priv.h: Added COND_global_read_lock sql/mysqld.cc: Added COND_global_read_lock sql/sql_base.cc: More DBUG statements Added a broadcast in remove_table_from_cache() to release any threads waiting in open
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc34
1 files changed, 25 insertions, 9 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 8ea13b2117c..71384fe7fc6 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1138,16 +1138,17 @@ bool lock_global_read_lock(THD *thd)
if (!thd->global_read_lock)
{
+ const char *old_message;
(void) pthread_mutex_lock(&LOCK_global_read_lock);
- const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
- "Waiting to get readlock");
+ old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
+ "Waiting to get readlock");
DBUG_PRINT("info",
("waiting_for: %d protect_against: %d",
waiting_for_read_lock, protect_against_global_read_lock));
waiting_for_read_lock++;
while (protect_against_global_read_lock && !thd->killed)
- pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
+ pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
waiting_for_read_lock--;
if (thd->killed)
{
@@ -1169,9 +1170,15 @@ bool lock_global_read_lock(THD *thd)
DBUG_RETURN(0);
}
+
void unlock_global_read_lock(THD *thd)
{
uint tmp;
+ DBUG_ENTER("unlock_global_read_lock");
+ DBUG_PRINT("info",
+ ("global_read_lock: %u global_read_lock_blocks_commit: %u",
+ global_read_lock, global_read_lock_blocks_commit));
+
pthread_mutex_lock(&LOCK_global_read_lock);
tmp= --global_read_lock;
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
@@ -1179,8 +1186,13 @@ void unlock_global_read_lock(THD *thd)
pthread_mutex_unlock(&LOCK_global_read_lock);
/* Send the signal outside the mutex to avoid a context switch */
if (!tmp)
- pthread_cond_broadcast(&COND_refresh);
+ {
+ DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
+ pthread_cond_broadcast(&COND_global_read_lock);
+ }
thd->global_read_lock= 0;
+
+ DBUG_VOID_RETURN;
}
#define must_wait (global_read_lock && \
@@ -1218,11 +1230,15 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
*/
DBUG_RETURN(is_not_commit);
}
- old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
+ old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
"Waiting for release of readlock");
while (must_wait && ! thd->killed &&
(!abort_on_refresh || thd->version == refresh_version))
- (void) pthread_cond_wait(&COND_refresh,&LOCK_global_read_lock);
+ {
+ DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
+ (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
+ DBUG_PRINT("signal", ("Got COND_global_read_lock"));
+ }
if (thd->killed)
result=1;
}
@@ -1251,7 +1267,7 @@ void start_waiting_global_read_lock(THD *thd)
(waiting_for_read_lock || global_read_lock_blocks_commit));
(void) pthread_mutex_unlock(&LOCK_global_read_lock);
if (tmp)
- pthread_cond_broadcast(&COND_refresh);
+ pthread_cond_broadcast(&COND_global_read_lock);
DBUG_VOID_RETURN;
}
@@ -1273,10 +1289,10 @@ bool make_global_read_lock_block_commit(THD *thd)
/* For testing we set up some blocking, to see if we can be killed */
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
protect_against_global_read_lock++;);
- old_message= thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
+ old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
"Waiting for all running commits to finish");
while (protect_against_global_read_lock && !thd->killed)
- pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
+ pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
protect_against_global_read_lock--;);
if ((error= test(thd->killed)))