1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug#16986 - Deadlock condition with MyISAM tables

Addendum fixes after changing the condition variable
for the global read lock.

The stress test suite revealed some deadlocks. Some were
related to the new condition variable (COND_global_read_lock)
and some were general problems with the global read lock.

It is now necessary to signal COND_global_read_lock whenever 
COND_refresh is signalled.

We need to wait for the release of a global read lock if one 
is set before every operation that requires a write lock.
But we must not wait if we have locked tables by LOCK TABLES.
After setting a global read lock a thread waits until all
write locks are released.
This commit is contained in:
ingo@mysql.com
2006-06-26 19:14:35 +02:00
parent fa98891ee7
commit d27a15a81c
10 changed files with 208 additions and 66 deletions

View File

@ -530,7 +530,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
if (found_old_table)
{
/* Tell threads waiting for refresh that something has happened */
VOID(pthread_cond_broadcast(&COND_refresh));
broadcast_refresh();
}
if (!lock_in_use)
VOID(pthread_mutex_unlock(&LOCK_open));
@ -1035,7 +1035,7 @@ TABLE *unlink_open_table(THD *thd, TABLE *list, TABLE *find)
}
*prev=0;
// Notify any 'refresh' threads
pthread_cond_broadcast(&COND_refresh);
broadcast_refresh();
return start;
}
@ -1577,7 +1577,7 @@ bool reopen_table(TABLE *table,bool locked)
if (table->triggers)
table->triggers->set_table(table);
VOID(pthread_cond_broadcast(&COND_refresh));
broadcast_refresh();
error=0;
end:
@ -1678,7 +1678,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
{
my_afree((gptr) tables);
}
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
broadcast_refresh();
*prev=0;
DBUG_RETURN(error);
}
@ -1715,7 +1715,7 @@ void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
}
}
if (found)
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
broadcast_refresh();
DBUG_VOID_RETURN;
}
@ -1807,7 +1807,7 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name)
}
*prev=0;
if (found)
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
broadcast_refresh();
if (thd->locked_tables && thd->locked_tables->table_count == 0)
{
my_free((gptr) thd->locked_tables,MYF(0));
@ -5249,7 +5249,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
Signal any thread waiting for tables to be freed to
reopen their tables
*/
(void) pthread_cond_broadcast(&COND_refresh);
broadcast_refresh();
DBUG_PRINT("info", ("Waiting for refresh signal"));
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
{