summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc31
1 files changed, 24 insertions, 7 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index e07b03f7bb1..decde918d9e 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -536,6 +536,9 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
const Security_context *sctx= &thd->main_security_ctx;
char header[256];
int len;
+
+ mysql_mutex_lock(&LOCK_thread_count);
+
/*
The pointers thd->query and thd->proc_info might change since they are
being modified concurrently. This is acceptable for proc_info since its
@@ -591,6 +594,7 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
}
mysql_mutex_unlock(&thd->LOCK_thd_data);
}
+ mysql_mutex_unlock(&LOCK_thread_count);
if (str.c_ptr_safe() == buffer)
return buffer;
@@ -782,6 +786,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
query_start_used= query_start_sec_part_used= 0;
count_cuted_fields= CHECK_FIELD_IGNORE;
killed= NOT_KILLED;
+ killed_err= 0;
col_access=0;
is_slave_error= thread_specific_used= FALSE;
my_hash_clear(&handler_tables_hash);
@@ -837,6 +842,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
#endif
mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_wakeup_ready, &LOCK_wakeup_ready, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_LOCK_thd_kill, &LOCK_thd_kill, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_COND_wakeup_ready, &COND_wakeup_ready, 0);
/*
LOCK_thread_count goes before LOCK_thd_data - the former is called around
@@ -1430,7 +1436,7 @@ void THD::cleanup(void)
DBUG_ENTER("THD::cleanup");
DBUG_ASSERT(cleanup_done == 0);
- killed= KILL_CONNECTION;
+ set_killed(KILL_CONNECTION);
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
if (transaction.xid_state.xa_state == XA_PREPARED)
{
@@ -1589,6 +1595,7 @@ THD::~THD()
mysql_cond_destroy(&COND_wakeup_ready);
mysql_mutex_destroy(&LOCK_wakeup_ready);
mysql_mutex_destroy(&LOCK_thd_data);
+ mysql_mutex_destroy(&LOCK_thd_kill);
#ifndef DBUG_OFF
dbug_sentry= THD_SENTRY_GONE;
#endif
@@ -1766,7 +1773,8 @@ void THD::awake(killed_state state_to_set)
state_to_set= killed;
/* Set the 'killed' flag of 'this', which is the target THD object. */
- killed= state_to_set;
+ mysql_mutex_lock(&LOCK_thd_kill);
+ set_killed_no_mutex(state_to_set);
if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED)
{
@@ -1852,6 +1860,7 @@ void THD::awake(killed_state state_to_set)
}
mysql_mutex_unlock(&mysys_var->mutex);
}
+ mysql_mutex_unlock(&LOCK_thd_kill);
DBUG_VOID_RETURN;
}
@@ -1869,7 +1878,7 @@ void THD::disconnect()
mysql_mutex_lock(&LOCK_thd_data);
- killed= KILL_CONNECTION;
+ set_killed(KILL_CONNECTION);
#ifdef SIGNAL_WITH_VIO_CLOSE
/*
@@ -1905,7 +1914,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
DBUG_PRINT("info", ("kill delayed thread"));
mysql_mutex_lock(&in_use->LOCK_thd_data);
if (in_use->killed < KILL_CONNECTION)
- in_use->killed= KILL_CONNECTION;
+ in_use->set_killed(KILL_CONNECTION);
if (in_use->mysys_var)
{
mysql_mutex_lock(&in_use->mysys_var->mutex);
@@ -1958,13 +1967,21 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
/*
Get error number for killed state
Note that the error message can't have any parameters.
+ If one needs parameters, one should use THD::killed_err_msg
See thd::kill_message()
*/
-int killed_errno(killed_state killed)
+int THD::killed_errno()
{
DBUG_ENTER("killed_errno");
- DBUG_PRINT("enter", ("killed: %d", killed));
+ DBUG_PRINT("enter", ("killed: %d killed_errno: %d",
+ killed, killed_err ? killed_err->no: 0));
+
+ /* Ensure that killed_err is not set if we are not killed */
+ DBUG_ASSERT(!killed_err || killed != NOT_KILLED);
+
+ if (killed_err)
+ DBUG_RETURN(killed_err->no);
switch (killed) {
case NOT_KILLED:
@@ -2420,7 +2437,7 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
{
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_FATALERROR),
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
- killed= KILL_CONNECTION;
+ set_killed(KILL_CONNECTION);
return 0;
}