diff options
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 320b9580ba3..f543d3b8dd4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8955,24 +8955,35 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields, pointer - thread found, and its LOCK_thd_kill is locked. */ -THD *find_thread_by_id(longlong id, bool query_id) +struct find_thread_callback_arg { - THD *tmp; - mysql_mutex_lock(&LOCK_thread_count); // For unlink from list - I_List_iterator<THD> it(threads); - while ((tmp=it++)) + find_thread_callback_arg(longlong id_arg, bool query_id_arg): + thd(0), id(id_arg), query_id(query_id_arg) {} + THD *thd; + longlong id; + bool query_id; +}; + + +my_bool find_thread_callback(THD *thd, find_thread_callback_arg *arg) +{ + if (thd->get_command() != COM_DAEMON && + arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id)) { - if (tmp->get_command() == COM_DAEMON) - continue; - if (id == (query_id ? tmp->query_id : (longlong) tmp->thread_id)) - { - if (WSREP(tmp)) mysql_mutex_lock(&tmp->LOCK_thd_data); - mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete - break; - } + if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data); + mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete + arg->thd= thd; + return 1; } - mysql_mutex_unlock(&LOCK_thread_count); - return tmp; + return 0; +} + + +THD *find_thread_by_id(longlong id, bool query_id) +{ + find_thread_callback_arg arg(id, query_id); + server_threads.iterate(find_thread_callback, &arg); + return arg.thd; } @@ -9056,53 +9067,63 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ are killed. */ -static uint kill_threads_for_user(THD *thd, LEX_USER *user, - killed_state kill_signal, ha_rows *rows) +struct kill_threads_callback_arg { - THD *tmp; + kill_threads_callback_arg(THD *thd_arg, LEX_USER *user_arg): + thd(thd_arg), user(user_arg) {} + THD *thd; + LEX_USER *user; List<THD> threads_to_kill; - DBUG_ENTER("kill_threads_for_user"); - - *rows= 0; - - if (unlikely(thd->is_fatal_error)) // If we run out of memory - DBUG_RETURN(ER_OUT_OF_RESOURCES); +}; - DBUG_PRINT("enter", ("user: %s signal: %u", user->user.str, - (uint) kill_signal)); - mysql_mutex_lock(&LOCK_thread_count); // For unlink from list - I_List_iterator<THD> it(threads); - while ((tmp=it++)) +static my_bool kill_threads_callback(THD *thd, kill_threads_callback_arg *arg) +{ + if (thd->security_ctx->user) { - if (!tmp->security_ctx->user) - continue; /* Check that hostname (if given) and user name matches. host.str[0] == '%' means that host name was not given. See sql_yacc.yy */ - if (((user->host.str[0] == '%' && !user->host.str[1]) || - !strcmp(tmp->security_ctx->host_or_ip, user->host.str)) && - !strcmp(tmp->security_ctx->user, user->user.str)) + if (((arg->user->host.str[0] == '%' && !arg->user->host.str[1]) || + !strcmp(thd->security_ctx->host_or_ip, arg->user->host.str)) && + !strcmp(thd->security_ctx->user, arg->user->user.str)) { - if (!(thd->security_ctx->master_access & SUPER_ACL) && - !thd->security_ctx->user_matches(tmp->security_ctx)) - { - mysql_mutex_unlock(&LOCK_thread_count); - DBUG_RETURN(ER_KILL_DENIED_ERROR); - } - if (!threads_to_kill.push_back(tmp, thd->mem_root)) + if (!(arg->thd->security_ctx->master_access & SUPER_ACL) && + !arg->thd->security_ctx->user_matches(thd->security_ctx)) + return 1; + if (!arg->threads_to_kill.push_back(thd, arg->thd->mem_root)) { - if (WSREP(tmp)) mysql_mutex_lock(&tmp->LOCK_thd_data); - mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete + if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data); + mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete } } } - mysql_mutex_unlock(&LOCK_thread_count); - if (!threads_to_kill.is_empty()) + return 0; +} + + +static uint kill_threads_for_user(THD *thd, LEX_USER *user, + killed_state kill_signal, ha_rows *rows) +{ + kill_threads_callback_arg arg(thd, user); + DBUG_ENTER("kill_threads_for_user"); + + *rows= 0; + + if (unlikely(thd->is_fatal_error)) // If we run out of memory + DBUG_RETURN(ER_OUT_OF_RESOURCES); + + DBUG_PRINT("enter", ("user: %s signal: %u", user->user.str, + (uint) kill_signal)); + + if (server_threads.iterate(kill_threads_callback, &arg)) + DBUG_RETURN(ER_KILL_DENIED_ERROR); + + if (!arg.threads_to_kill.is_empty()) { - List_iterator_fast<THD> it2(threads_to_kill); + List_iterator_fast<THD> it2(arg.threads_to_kill); THD *next_ptr; THD *ptr= it2++; do |