Commit 8ff0a7f8 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

Implement DEBUG_SYNC multiple signal firing capability

One can now do:
set DEBUG_SYNC='... SIGNAL s1,s2,s3...'

Multiple signals can be fired, they need to be split by commas.
parent c115559b
...@@ -315,4 +315,8 @@ SET DEBUG_SYNC= 'now WAIT_FOR s1'; ...@@ -315,4 +315,8 @@ SET DEBUG_SYNC= 'now WAIT_FOR s1';
SHOW VARIABLES LIKE 'DEBUG_SYNC'; SHOW VARIABLES LIKE 'DEBUG_SYNC';
Variable_name Value Variable_name Value
debug_sync ON - current signals: '' debug_sync ON - current signals: ''
SET DEBUG_SYNC= 'now SIGNAL s1,s2,s5,s7';
SHOW VARIABLES LIKE 'DEBUG_SYNC';
Variable_name Value
debug_sync ON - current signals: 's2,s7,s1,s5'
SET DEBUG_SYNC= 'RESET'; SET DEBUG_SYNC= 'RESET';
...@@ -439,10 +439,13 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC'; ...@@ -439,10 +439,13 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC';
SET DEBUG_SYNC= 'now WAIT_FOR s1'; SET DEBUG_SYNC= 'now WAIT_FOR s1';
SHOW VARIABLES LIKE 'DEBUG_SYNC'; SHOW VARIABLES LIKE 'DEBUG_SYNC';
SET DEBUG_SYNC= 'now SIGNAL s1,s2,s5,s7';
SHOW VARIABLES LIKE 'DEBUG_SYNC';
# #
# Cleanup after test case. # Cleanup after test case.
# Otherwise signal would contain 'flushed' here, # Otherwise signal would confuse the next test.
# which could confuse the next test.
# #
SET DEBUG_SYNC= 'RESET'; SET DEBUG_SYNC= 'RESET';
...@@ -122,9 +122,9 @@ struct st_debug_sync_globals ...@@ -122,9 +122,9 @@ struct st_debug_sync_globals
@retval false otherwise. @retval false otherwise.
*/ */
inline bool is_signalled(const String &signal_name) inline bool is_signalled(const char *signal_name, size_t length)
{ {
return ds_signal_set.find(signal_name.ptr(), signal_name.length()); return ds_signal_set.find(signal_name, length);
} }
void clear_signal(const String &signal_name) void clear_signal(const String &signal_name)
...@@ -140,21 +140,21 @@ struct st_debug_sync_globals ...@@ -140,21 +140,21 @@ struct st_debug_sync_globals
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
bool set_signal(const String &signal_name) bool set_signal(const char *signal_name, size_t length)
{ {
/* Need to check if the signal is already in the hash set, because /* Need to check if the signal is already in the hash set, because
Hash_set doesn't differentiate between OOM and key already in. */ Hash_set doesn't differentiate between OOM and key already in. */
if (is_signalled(signal_name)) if (is_signalled(signal_name, length))
return FALSE; return FALSE;
/* LEX_CSTRING and the string allocated with only one malloc. */ /* LEX_CSTRING and the string allocated with only one malloc. */
LEX_CSTRING *s= (LEX_CSTRING *) my_malloc(PSI_NOT_INSTRUMENTED, LEX_CSTRING *s= (LEX_CSTRING *) my_malloc(PSI_NOT_INSTRUMENTED,
sizeof(LEX_CSTRING) + sizeof(LEX_CSTRING) + length + 1,
signal_name.length() + 1, MYF(0)); MYF(0));
char *str= (char *)(s + 1); char *str= (char *)(s + 1);
memcpy(str, signal_name.ptr(), signal_name.length()); memcpy(str, signal_name, length);
str[signal_name.length()]= '\0'; str[length]= '\0';
s->length= signal_name.length(); s->length= length;
s->str= str; s->str= str;
if (ds_signal_set.insert(s)) if (ds_signal_set.insert(s))
return TRUE; return TRUE;
...@@ -1522,7 +1522,23 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) ...@@ -1522,7 +1522,23 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
if (action->signal.length()) if (action->signal.length())
{ {
if (debug_sync_global.set_signal(action->signal)) int offset= 0, pos;
bool error= false;
/* This loop covers all signals in the list except for the last one.
Split the signal string by commas and set a signal in the global
variable for each one. */
while (!error && (pos= action->signal.strstr(",", 1, offset)) > 0)
{
error= debug_sync_global.set_signal(action->signal.ptr() + offset,
pos - offset);
offset= pos + 1;
}
if (error ||
/* The last signal in the list. */
debug_sync_global.set_signal(action->signal.ptr() + offset,
action->signal.length() - offset))
{ {
/* /*
Error is reported by my_malloc(). Error is reported by my_malloc().
...@@ -1578,8 +1594,9 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) ...@@ -1578,8 +1594,9 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
The facility can become disabled when some thread cannot get The facility can become disabled when some thread cannot get
the required dynamic memory allocated. the required dynamic memory allocated.
*/ */
while (!debug_sync_global.is_signalled(action->wait_for) && while (!debug_sync_global.is_signalled(action->wait_for.ptr(),
!(thd->killed & KILL_HARD_BIT)&& action->wait_for.length()) &&
!(thd->killed & KILL_HARD_BIT) &&
opt_debug_sync_timeout) opt_debug_sync_timeout)
{ {
error= mysql_cond_timedwait(&debug_sync_global.ds_cond, error= mysql_cond_timedwait(&debug_sync_global.ds_cond,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment