Skip to content

Commit 7f38a07

Browse files
committed
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.
1 parent 128930c commit 7f38a07

File tree

1 file changed

+7
-26
lines changed

1 file changed

+7
-26
lines changed

sql/event_scheduler.cc

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,6 @@ post_init_event_thread(THD *thd)
131131
thd->cleanup();
132132
return TRUE;
133133
}
134-
135-
mysql_mutex_lock(&LOCK_thread_count);
136-
threads.append(thd);
137-
thread_count++;
138-
inc_thread_running();
139-
mysql_mutex_unlock(&LOCK_thread_count);
140134
return FALSE;
141135
}
142136

@@ -158,7 +152,6 @@ deinit_event_thread(THD *thd)
158152
DBUG_PRINT("exit", ("Event thread finishing"));
159153
mysql_mutex_lock(&LOCK_thread_count);
160154
thread_count--;
161-
dec_thread_running();
162155
delete thd;
163156
mysql_cond_broadcast(&COND_thread_count);
164157
mysql_mutex_unlock(&LOCK_thread_count);
@@ -195,6 +188,8 @@ pre_init_event_thread(THD* thd)
195188
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
196189
mysql_mutex_lock(&LOCK_thread_count);
197190
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
191+
threads.append(thd);
192+
thread_count++;
198193
mysql_mutex_unlock(&LOCK_thread_count);
199194

200195
/*
@@ -241,13 +236,8 @@ event_scheduler_thread(void *arg)
241236
my_free(arg);
242237
if (!res)
243238
scheduler->run(thd);
244-
else
245-
{
246-
thd->proc_info= "Clearing";
247-
net_end(&thd->net);
248-
delete thd;
249-
}
250239

240+
deinit_event_thread(thd);
251241
DBUG_LEAVE; // Against gcc warnings
252242
my_thread_end();
253243
return 0;
@@ -308,6 +298,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
308298
DBUG_ENTER("Event_worker_thread::run");
309299
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd));
310300

301+
inc_thread_running();
311302
if (res)
312303
goto end;
313304

@@ -334,6 +325,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
334325
event->name.str));
335326

336327
delete event;
328+
dec_thread_running();
337329
deinit_event_thread(thd);
338330

339331
DBUG_VOID_RETURN;
@@ -432,13 +424,9 @@ Event_scheduler::start(int *err_no)
432424
" Can not create thread for event scheduler (errno=%d)",
433425
*err_no);
434426

435-
new_thd->proc_info= "Clearing";
436-
DBUG_ASSERT(new_thd->net.buff != 0);
437-
net_end(&new_thd->net);
438-
439427
state= INITIALIZED;
440428
scheduler_thd= NULL;
441-
delete new_thd;
429+
deinit_event_thread(new_thd);
442430

443431
delete scheduler_param_value;
444432
ret= true;
@@ -505,7 +493,6 @@ Event_scheduler::run(THD *thd)
505493
}
506494

507495
LOCK_DATA();
508-
deinit_event_thread(thd);
509496
scheduler_thd= NULL;
510497
state= INITIALIZED;
511498
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)
564551
sql_print_error("Event_scheduler::execute_top: Can not create event worker"
565552
" thread (errno=%d). Stopping event scheduler", res);
566553

567-
new_thd->proc_info= "Clearing";
568-
DBUG_ASSERT(new_thd->net.buff != 0);
569-
net_end(&new_thd->net);
570-
554+
deinit_event_thread(new_thd);
571555
goto error;
572556
}
573557

@@ -579,9 +563,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
579563

580564
error:
581565
DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res));
582-
if (new_thd)
583-
delete new_thd;
584-
585566
delete event_name;
586567
DBUG_RETURN(TRUE);
587568
}

0 commit comments

Comments
 (0)