summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2016-06-17 18:54:11 +0400
committerSergey Vojtovich <svoj@mariadb.org>2016-06-20 15:17:10 +0400
commit7f38a070baa503a37af186ff24f39606816f55ec (patch)
treeede921ca4bb2506a0fc42c595d035ff99f0905cd /sql
parent128930c19b4ebc6a50f254bcee6af84db79ebe91 (diff)
downloadmariadb-git-7f38a070baa503a37af186ff24f39606816f55ec.tar.gz
MDEV-10043 - main.events_restart fails sporadically in buildbot (crashes upon
shutdown) There was race condition between shutdown thread and event worker threads. Shutdown thread waits for thread_count to become 0 in close_connections(). It may happen so that event worker thread was started but didn't increment thread_count by this time. In this case shutdown thread may miss wait for this working thread and continue deinitialization. Worker thread in turn may continue execution and crash on deinitialized data. Fixed by incrementing thread_count before thread is actually created like it is done for connection threads. Also let event scheduler not to inc/dec running threads counter for symmetry with other "service" threads.
Diffstat (limited to 'sql')
-rw-r--r--sql/event_scheduler.cc33
1 files changed, 7 insertions, 26 deletions
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index beb3c864662..a5a3f7110b3 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -131,12 +131,6 @@ post_init_event_thread(THD *thd)
thd->cleanup();
return TRUE;
}
-
- mysql_mutex_lock(&LOCK_thread_count);
- threads.append(thd);
- thread_count++;
- inc_thread_running();
- mysql_mutex_unlock(&LOCK_thread_count);
return FALSE;
}
@@ -158,7 +152,6 @@ deinit_event_thread(THD *thd)
DBUG_PRINT("exit", ("Event thread finishing"));
mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
- dec_thread_running();
delete thd;
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
@@ -195,6 +188,8 @@ pre_init_event_thread(THD* thd)
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
mysql_mutex_lock(&LOCK_thread_count);
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
+ threads.append(thd);
+ thread_count++;
mysql_mutex_unlock(&LOCK_thread_count);
/*
@@ -241,13 +236,8 @@ event_scheduler_thread(void *arg)
my_free(arg);
if (!res)
scheduler->run(thd);
- else
- {
- thd->proc_info= "Clearing";
- net_end(&thd->net);
- delete thd;
- }
+ deinit_event_thread(thd);
DBUG_LEAVE; // Against gcc warnings
my_thread_end();
return 0;
@@ -308,6 +298,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd));
+ inc_thread_running();
if (res)
goto end;
@@ -334,6 +325,7 @@ end:
event->name.str));
delete event;
+ dec_thread_running();
deinit_event_thread(thd);
DBUG_VOID_RETURN;
@@ -432,13 +424,9 @@ Event_scheduler::start(int *err_no)
" Can not create thread for event scheduler (errno=%d)",
*err_no);
- new_thd->proc_info= "Clearing";
- DBUG_ASSERT(new_thd->net.buff != 0);
- net_end(&new_thd->net);
-
state= INITIALIZED;
scheduler_thd= NULL;
- delete new_thd;
+ deinit_event_thread(new_thd);
delete scheduler_param_value;
ret= true;
@@ -505,7 +493,6 @@ Event_scheduler::run(THD *thd)
}
LOCK_DATA();
- deinit_event_thread(thd);
scheduler_thd= NULL;
state= INITIALIZED;
DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers"));
@@ -564,10 +551,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
sql_print_error("Event_scheduler::execute_top: Can not create event worker"
" thread (errno=%d). Stopping event scheduler", res);
- new_thd->proc_info= "Clearing";
- DBUG_ASSERT(new_thd->net.buff != 0);
- net_end(&new_thd->net);
-
+ deinit_event_thread(new_thd);
goto error;
}
@@ -579,9 +563,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
error:
DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res));
- if (new_thd)
- delete new_thd;
-
delete event_name;
DBUG_RETURN(TRUE);
}