diff options
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 31 |
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; } |