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