cleanup: THD::abort_current_cond_wait()

* reuse the loop in THD::abort_current_cond_wait, don't duplicate it
* find_thread_by_id should return whatever it has found, it's the
  caller's task not to kill COM_DAEMON (if the caller's a killer)

and other minor changes
This commit is contained in:
Sergei Golubchik 2021-02-05 15:00:38 +01:00
parent cbbcc8fa2b
commit 259a1902a0
7 changed files with 34 additions and 87 deletions

View File

@ -1523,27 +1523,7 @@ static void kill_thread(THD *thd)
{
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_kill);
if (thd->mysys_var)
{
thd->mysys_var->abort= 1;
mysql_mutex_lock(&thd->mysys_var->mutex);
if (thd->mysys_var->current_cond)
{
for (uint i= 0; i < 2; i++)
{
int ret= mysql_mutex_trylock(thd->mysys_var->current_mutex);
mysql_cond_broadcast(thd->mysys_var->current_cond);
if (!ret)
{
/* Thread has surely got the signal, unlock and abort */
mysql_mutex_unlock(thd->mysys_var->current_mutex);
break;
}
sleep(1);
}
}
mysql_mutex_unlock(&thd->mysys_var->mutex);
}
thd->abort_current_cond_wait(true);
mysql_mutex_unlock(&thd->LOCK_thd_kill);
if (WSREP(thd)) mysql_mutex_unlock(&thd->LOCK_thd_data);
}

View File

@ -49,9 +49,6 @@
#include <m_ctype.h>
#include <sys/stat.h>
#include <thr_alarm.h>
#ifdef __WIN__0
#include <io.h>
#endif
#include <mysys_err.h>
#include <limits.h>
@ -70,6 +67,8 @@
#ifdef WITH_WSREP
#include "wsrep_thd.h"
#include "wsrep_trans_observer.h"
#else
static inline bool wsrep_is_bf_aborted(THD* thd) { return false; }
#endif /* WITH_WSREP */
#include "opt_trace.h"
@ -1902,15 +1901,21 @@ void THD::awake_no_mutex(killed_state state_to_set)
}
/* Interrupt target waiting inside a storage engine. */
if (IF_WSREP(state_to_set != NOT_KILLED && !wsrep_is_bf_aborted(this),
state_to_set != NOT_KILLED))
if (state_to_set != NOT_KILLED && !wsrep_is_bf_aborted(this))
ha_kill_query(this, thd_kill_level(this));
/* Broadcast a condition to kick the target if it is waiting on it. */
abort_current_cond_wait(false);
DBUG_VOID_RETURN;
}
/* Broadcast a condition to kick the target if it is waiting on it. */
void THD::abort_current_cond_wait(bool force)
{
mysql_mutex_assert_owner(&LOCK_thd_kill);
if (mysys_var)
{
mysql_mutex_lock(&mysys_var->mutex);
if (!system_thread) // Don't abort locks
if (!system_thread || force) // Don't abort locks
mysys_var->abort=1;
/*
@ -1968,7 +1973,6 @@ void THD::awake_no_mutex(killed_state state_to_set)
}
mysql_mutex_unlock(&mysys_var->mutex);
}
DBUG_VOID_RETURN;
}
@ -2022,16 +2026,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
mysql_mutex_lock(&in_use->LOCK_thd_kill);
if (in_use->killed < KILL_CONNECTION)
in_use->set_killed_no_mutex(KILL_CONNECTION);
if (in_use->mysys_var)
{
mysql_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
mysql_cond_broadcast(in_use->mysys_var->current_cond);
/* Abort if about to wait in thr_upgrade_write_delay_lock */
in_use->mysys_var->abort= 1;
mysql_mutex_unlock(&in_use->mysys_var->mutex);
}
in_use->abort_current_cond_wait(true);
mysql_mutex_unlock(&in_use->LOCK_thd_kill);
signalled= TRUE;
}

View File

@ -3322,6 +3322,7 @@ public:
if (wsrep_on_local)
mysql_mutex_unlock(&LOCK_thd_data);
}
void abort_current_cond_wait(bool force);
/** Disconnect the associated communication endpoint. */
void disconnect();
@ -4061,8 +4062,7 @@ public:
mysql_mutex_lock(&LOCK_thd_kill);
int err= killed_errno();
if (err)
my_message(err, killed_err ? killed_err->msg : ER_THD(this, err),
MYF(0));
my_message(err, killed_err ? killed_err->msg : ER_THD(this, err), MYF(0));
mysql_mutex_unlock(&LOCK_thd_kill);
}
/* return TRUE if we will abort query if we make a warning now */

View File

@ -2869,23 +2869,7 @@ void kill_delayed_threads(void)
mysql_mutex_lock(&di->thd.LOCK_thd_kill);
if (di->thd.killed < KILL_CONNECTION)
di->thd.set_killed_no_mutex(KILL_CONNECTION);
if (di->thd.mysys_var)
{
mysql_mutex_lock(&di->thd.mysys_var->mutex);
if (di->thd.mysys_var->current_cond)
{
/*
We need the following test because the main mutex may be locked
in handle_delayed_insert()
*/
if (&di->mutex != di->thd.mysys_var->current_mutex)
mysql_mutex_lock(di->thd.mysys_var->current_mutex);
mysql_cond_broadcast(di->thd.mysys_var->current_cond);
if (&di->mutex != di->thd.mysys_var->current_mutex)
mysql_mutex_unlock(di->thd.mysys_var->current_mutex);
}
mysql_mutex_unlock(&di->thd.mysys_var->mutex);
}
di->thd.abort_current_cond_wait(false);
mysql_mutex_unlock(&di->thd.LOCK_thd_kill);
}
mysql_mutex_unlock(&LOCK_delayed_insert); // For unlink from list

View File

@ -9079,10 +9079,9 @@ struct find_thread_callback_arg
};
my_bool find_thread_callback(THD *thd, find_thread_callback_arg *arg)
static my_bool find_thread_callback(THD *thd, find_thread_callback_arg *arg)
{
if (thd->get_command() != COM_DAEMON &&
arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id))
if (arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id))
{
mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete
arg->thd= thd;
@ -9100,10 +9099,9 @@ THD *find_thread_by_id(longlong id, bool query_id)
}
#ifdef WITH_WSREP
my_bool find_thread_with_thd_data_lock_callback(THD *thd, find_thread_callback_arg *arg)
static my_bool find_thread_with_thd_data_lock_callback(THD *thd, find_thread_callback_arg *arg)
{
if (thd->get_command() != COM_DAEMON &&
arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id))
if (arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id))
{
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete
@ -9137,10 +9135,14 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
DBUG_ENTER("kill_one_thread");
DBUG_PRINT("enter", ("id: %lld signal: %u", id, (uint) kill_signal));
#ifdef WITH_WSREP
if (id && (tmp= find_thread_by_id_with_thd_data_lock(id, type == KILL_TYPE_QUERY)))
tmp= find_thread_by_id_with_thd_data_lock(id, type == KILL_TYPE_QUERY);
#else
if (id && (tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY)))
tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY);
#endif
if (!tmp)
DBUG_RETURN(error);
if (tmp->get_command() != COM_DAEMON)
{
/*
If we're SUPER, we can KILL anything, including system-threads.
@ -9194,11 +9196,11 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
else
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
ER_KILL_DENIED_ERROR);
#ifdef WITH_WSREP
if (WSREP(tmp)) mysql_mutex_unlock(&tmp->LOCK_thd_data);
#endif
mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
#ifdef WITH_WSREP
if (WSREP(tmp)) mysql_mutex_unlock(&tmp->LOCK_thd_data);
#endif
mysql_mutex_unlock(&tmp->LOCK_thd_kill);
DBUG_PRINT("exit", ("%d", error));
DBUG_RETURN(error);
}

View File

@ -3256,11 +3256,8 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
}
DBUG_RETURN(bres);
}
else
{
my_error(ER_NO_SUCH_THREAD, MYF(0), (ulong) thread_id);
DBUG_RETURN(1);
}
my_error(ER_NO_SUCH_THREAD, MYF(0), (ulong) thread_id);
DBUG_RETURN(1);
}

View File

@ -2384,18 +2384,7 @@ static void wsrep_close_thread(THD *thd)
thd->set_killed(KILL_CONNECTION);
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd));
mysql_mutex_lock(&thd->LOCK_thd_kill);
if (thd->mysys_var)
{
thd->mysys_var->abort=1;
mysql_mutex_lock(&thd->mysys_var->mutex);
if (thd->mysys_var->current_cond)
{
mysql_mutex_lock(thd->mysys_var->current_mutex);
mysql_cond_broadcast(thd->mysys_var->current_cond);
mysql_mutex_unlock(thd->mysys_var->current_mutex);
}
mysql_mutex_unlock(&thd->mysys_var->mutex);
}
thd->abort_current_cond_wait(true);
mysql_mutex_unlock(&thd->LOCK_thd_kill);
}