From 10272f3709be9dd0bd7871c70b252827c9c5f000 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Mon, 15 Apr 2024 10:23:22 +0200 Subject: [PATCH] Distinguish "manager stopped" from "manager not started" This way, if manager thread somehow starts and stops again quickly before main thread wakes up to check if it started correctly, we will not hang. Patch suggested by Monty as follow-up to 7f498fbab888bd24d76a0292f4d22cacfb2f95b2 Signed-off-by: Kristian Nielsen --- sql/sql_manager.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 5cd66d8047a..a286497235e 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -26,6 +26,10 @@ #include "sql_manager.h" #include "sql_base.h" // flush_tables +/* + Values for manager_thread_in_use: 0 means "not started". 1 means "started + and active". 2 means "stopped". +*/ static bool volatile manager_thread_in_use = 0; static bool abort_manager = false; @@ -44,7 +48,7 @@ static struct handler_cb *cb_list; // protected by LOCK_manager bool mysql_manager_submit(void (*action)(void *), void *data) { bool result= FALSE; - DBUG_ASSERT(manager_thread_in_use); + DBUG_ASSERT(manager_thread_in_use == 1); struct handler_cb **cb; mysql_mutex_lock(&LOCK_manager); cb= &cb_list; @@ -119,7 +123,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) mysql_mutex_lock(&LOCK_manager); } DBUG_ASSERT(cb_list == NULL); - manager_thread_in_use = 0; + manager_thread_in_use = 2; mysql_mutex_unlock(&LOCK_manager); mysql_mutex_destroy(&LOCK_manager); mysql_cond_destroy(&COND_manager); @@ -148,6 +152,15 @@ void start_handle_manager() } mysql_mutex_lock(&LOCK_manager); + /* + Wait for manager thread to have started, otherwise in extreme cases the + server may start up and have initiated shutdown at the time the manager + thread even starts to run. + + Allow both values 1 and 2 for manager_thread_in_use, so that we will not + get stuck here if the manager thread somehow manages to start up and + abort again before we have time to test it here. + */ while (!manager_thread_in_use) mysql_cond_wait(&COND_manager, &LOCK_manager); mysql_mutex_unlock(&LOCK_manager);