summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <kostja@vajra.(none)>2007-04-06 19:44:14 +0400
committerunknown <kostja@vajra.(none)>2007-04-06 19:44:14 +0400
commitc557623a68b2c09ec7fd319b6a58d624dd2c2413 (patch)
tree562c4b97885c7356e30426e3c31055d9fb47d237
parent306be7fee9e41b02e54941099e25fba630a13580 (diff)
downloadmariadb-git-c557623a68b2c09ec7fd319b6a58d624dd2c2413.tar.gz
Remove a race between Event Scheduler shutdown and SHOW PROCESSLIST.
This will hopefully fix events.test failure on vmware-win32, where scheduling is very primitive. mysql-test/t/events_scheduling.test: This test case has no races now and can be enabled under valgrind. sql/event_scheduler.cc: Make Event Scheduler thread shutdown more synchronous: report successful shutdown only after having removed the scheduler thread from the global list of threads. This ensures that after the scheduler has been stopped, its thread is not present in SHOW PROCESSLIST output.
-rw-r--r--mysql-test/t/events_scheduling.test1
-rw-r--r--sql/event_scheduler.cc24
2 files changed, 7 insertions, 18 deletions
diff --git a/mysql-test/t/events_scheduling.test b/mysql-test/t/events_scheduling.test
index 5b839e25910..31c09a3d561 100644
--- a/mysql-test/t/events_scheduling.test
+++ b/mysql-test/t/events_scheduling.test
@@ -1,6 +1,5 @@
# Can't test with embedded server that doesn't support grants
-- source include/not_embedded.inc
--- source include/not_valgrind.inc
CREATE DATABASE IF NOT EXISTS events_test;
USE events_test;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index fa5cde9a43a..0603a299079 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -154,8 +154,6 @@ deinit_event_thread(THD *thd)
thread_running--;
delete thd;
pthread_mutex_unlock(&LOCK_thread_count);
-
- my_thread_end();
}
@@ -231,8 +229,7 @@ event_scheduler_thread(void *arg)
if (!res)
scheduler->run(thd);
- deinit_event_thread(thd);
- pthread_exit(0);
+ my_thread_end();
DBUG_RETURN(0); // Against gcc warnings
}
@@ -260,6 +257,7 @@ event_worker_thread(void *arg)
Event_worker_thread worker_thread;
worker_thread.run(thd, event);
+ my_thread_end();
return 0; // Can't return anything here
}
@@ -494,12 +492,14 @@ Event_scheduler::run(THD *thd)
}
DBUG_PRINT("info", ("state=%s", scheduler_states_names[state].str));
}
+
LOCK_DATA();
- DBUG_PRINT("info", ("Signalling back to the stopper COND_state"));
+ deinit_event_thread(thd);
+ scheduler_thd= NULL;
state= INITIALIZED;
+ DBUG_PRINT("info", ("Signalling back to the stopper COND_state"));
pthread_cond_signal(&COND_state);
UNLOCK_DATA();
- sql_print_information("Event Scheduler: Stopped");
DBUG_RETURN(res);
}
@@ -651,17 +651,7 @@ Event_scheduler::stop()
COND_STATE_WAIT(thd, NULL, "Waiting scheduler to stop");
} while (state == STOPPING);
DBUG_PRINT("info", ("Scheduler thread has cleaned up. Set state to INIT"));
- /*
- The rationale behind setting it to NULL here but not destructing it
- beforehand is because the THD will be deinited in event_scheduler_thread().
- It's more clear when the post_init and the deinit is done in one function.
- Here we just mark that the scheduler doesn't have a THD anymore. Though for
- milliseconds the old thread could exist we can't use it anymore. When we
- unlock the mutex in this function a little later the state will be
- INITIALIZED. Therefore, a connection thread could enter the critical section
- and will create a new THD object.
- */
- scheduler_thd= NULL;
+ sql_print_information("Event Scheduler: Stopped");
end:
UNLOCK_DATA();
DBUG_RETURN(FALSE);