summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc16
1 files changed, 13 insertions, 3 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7092ea3bb6c..167abfeedc6 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -6674,13 +6674,23 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
if (!threads_to_kill.is_empty())
{
List_iterator_fast<THD> it(threads_to_kill);
- THD *ptr;
- while ((ptr= it++))
+ THD *next_ptr;
+ THD *ptr= it++;
+ do
{
ptr->awake(kill_signal);
+ /*
+ Careful here: The list nodes are allocated on the memroots of the
+ THDs to be awakened.
+ But those THDs may be terminated and deleted as soon as we release
+ LOCK_thd_data, which will make the list nodes invalid.
+ Since the operation "it++" dereferences the "next" pointer of the
+ previous list node, we need to do this while holding LOCK_thd_data.
+ */
+ next_ptr= it++;
mysql_mutex_unlock(&ptr->LOCK_thd_data);
(*rows)++;
- }
+ } while ((ptr= next_ptr));
}
DBUG_RETURN(0);
}