summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2012-02-10 21:20:32 +0100
committerunknown <knielsen@knielsen-hq.org>2012-02-10 21:20:32 +0100
commite76a0476cc1774d1e9e0efc9db165b2e848c6318 (patch)
tree79775873338b9c36a5bb8c5b5f13dd1854fb3d7f /sql/sql_parse.cc
parentf6cdddf51f385fd7dd9afe286f3bdce0b7e59f60 (diff)
parent3d61c1399dc74e651030418730da429ee0b4e38a (diff)
downloadmariadb-git-e76a0476cc1774d1e9e0efc9db165b2e848c6318.tar.gz
Merge fix for lp:910817: Race condition in kill_threads_for_user().
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 24976ff9f1a..e84750369f9 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -7366,13 +7366,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++;
pthread_mutex_unlock(&ptr->LOCK_thd_data);
(*rows)++;
- }
+ } while ((ptr= next_ptr));
}
DBUG_RETURN(0);
}