diff options
author | unknown <knielsen@knielsen-hq.org> | 2012-02-10 21:20:32 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2012-02-10 21:20:32 +0100 |
commit | e76a0476cc1774d1e9e0efc9db165b2e848c6318 (patch) | |
tree | 79775873338b9c36a5bb8c5b5f13dd1854fb3d7f /sql/sql_parse.cc | |
parent | f6cdddf51f385fd7dd9afe286f3bdce0b7e59f60 (diff) | |
parent | 3d61c1399dc74e651030418730da429ee0b4e38a (diff) | |
download | mariadb-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.cc | 16 |
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); } |