diff options
Diffstat (limited to 'sql/event_scheduler.cc')
-rw-r--r-- | sql/event_scheduler.cc | 133 |
1 files changed, 75 insertions, 58 deletions
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 240d2df8e65..55a3f6b36c4 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2006 MySQL AB +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,14 +11,17 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "mysql_priv.h" +#include "sql_priv.h" +#include "unireg.h" +#include "event_scheduler.h" #include "events.h" #include "event_data_objects.h" -#include "event_scheduler.h" #include "event_queue.h" #include "event_db_repository.h" +#include "sql_connect.h" // init_new_connection_handler_thread +#include "sql_acl.h" // SUPER_ACL /** @addtogroup Event_Scheduler @@ -74,7 +77,7 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) { MYSQL_ERROR *err; DBUG_ENTER("evex_print_warnings"); - if (!thd->warn_list.elements) + if (thd->warning_info->is_empty()) DBUG_VOID_RETURN; char msg_buf[10 * STRING_BUFFER_USUAL_SIZE]; @@ -90,17 +93,18 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) prefix.append(et->name.str, et->name.length, system_charset_info); prefix.append("] ", 2); - List_iterator_fast<MYSQL_ERROR> it(thd->warn_list); + List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list()); while ((err= it++)) { String err_msg(msg_buf, sizeof(msg_buf), system_charset_info); /* set it to 0 or we start adding at the end. That's the trick ;) */ err_msg.length(0); err_msg.append(prefix); - err_msg.append(err->msg, strlen(err->msg), system_charset_info); - DBUG_ASSERT(err->level < 3); - (sql_print_message_handlers[err->level])("%*s", err_msg.length(), - err_msg.c_ptr_safe()); + err_msg.append(err->get_message_text(), + err->get_message_octet_length(), system_charset_info); + DBUG_ASSERT(err->get_level() < 3); + (sql_print_message_handlers[err->get_level()])("%*s", err_msg.length(), + err_msg.c_ptr_safe()); } DBUG_VOID_RETURN; } @@ -127,14 +131,12 @@ post_init_event_thread(THD *thd) thd->cleanup(); return TRUE; } - lex_start(thd); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); threads.append(thd); thread_count++; - thread_running++; - pthread_mutex_unlock(&LOCK_thread_count); - + inc_thread_running(); + mysql_mutex_unlock(&LOCK_thread_count); return FALSE; } @@ -154,17 +156,17 @@ deinit_event_thread(THD *thd) DBUG_ASSERT(thd->net.buff != 0); net_end(&thd->net); DBUG_PRINT("exit", ("Event thread finishing")); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; + dec_thread_running(); delete thd; - pthread_cond_broadcast(&COND_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); } /* - Performs pre- pthread_create() initialisation of THD. Do this + Performs pre- mysql_thread_create() initialisation of THD. Do this in the thread that will pass THD to the child thread. In the child thread call post_init_event_thread(). @@ -189,11 +191,11 @@ pre_init_event_thread(THD* thd) thd->security_ctx->set_user((char*)"event_scheduler"); thd->net.read_timeout= slave_net_timeout; thd->slave_thread= 0; - thd->options|= OPTION_AUTO_IS_NULL; + thd->variables.option_bits|= OPTION_AUTO_IS_NULL; thd->client_capabilities|= CLIENT_MULTI_RESULTS; - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); /* Guarantees that we will see the thread in SHOW PROCESSLIST though its @@ -201,9 +203,11 @@ pre_init_event_thread(THD* thd) */ thd->proc_info= "Initialized"; - thd->version= refresh_version; thd->set_time(); + /* Do not use user-supplied timeout value for system threads. */ + thd->variables.lock_wait_timeout= LONG_TIMEOUT; + DBUG_VOID_RETURN; } @@ -228,10 +232,13 @@ event_scheduler_thread(void *arg) bool res; thd->thread_stack= (char *)&thd; // remember where our stack is + + mysql_thread_set_psi_id(thd->thread_id); + res= post_init_event_thread(thd); DBUG_ENTER("event_scheduler_thread"); - my_free((char*)arg, MYF(0)); + my_free(arg); if (!res) scheduler->run(thd); @@ -261,6 +268,8 @@ event_worker_thread(void *arg) thd= event->thd; + mysql_thread_set_psi_id(thd->thread_id); + Event_worker_thread worker_thread; worker_thread.run(thd, event); @@ -337,15 +346,16 @@ Event_scheduler::Event_scheduler(Event_queue *queue_arg) waiting_on_cond(FALSE), started_events(0) { - pthread_mutex_init(&LOCK_scheduler_state, MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_state, NULL); + mysql_mutex_init(key_event_scheduler_LOCK_scheduler_state, + &LOCK_scheduler_state, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_event_scheduler_COND_state, &COND_state, NULL); #ifdef SAFE_MUTEX /* Ensure right mutex order */ - pthread_mutex_lock(&LOCK_scheduler_state); - pthread_mutex_lock(&LOCK_global_system_variables); - pthread_mutex_unlock(&LOCK_global_system_variables); - pthread_mutex_unlock(&LOCK_scheduler_state); + mysql_mutex_lock(&LOCK_scheduler_state); + mysql_mutex_lock(&LOCK_global_system_variables); + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_mutex_unlock(&LOCK_scheduler_state); #endif } @@ -353,8 +363,8 @@ Event_scheduler::Event_scheduler(Event_queue *queue_arg) Event_scheduler::~Event_scheduler() { stop(); /* does nothing if not running */ - pthread_mutex_destroy(&LOCK_scheduler_state); - pthread_cond_destroy(&COND_state); + mysql_mutex_destroy(&LOCK_scheduler_state); + mysql_cond_destroy(&COND_state); } @@ -413,8 +423,9 @@ Event_scheduler::start() DBUG_PRINT("info", ("Setting state go RUNNING")); state= RUNNING; DBUG_PRINT("info", ("Forking new thread for scheduler. THD: 0x%lx", (long) new_thd)); - if (pthread_create(&th, &connection_attrib, event_scheduler_thread, - (void*)scheduler_param_value)) + if (mysql_thread_create(key_thread_event_scheduler, + &th, &connection_attrib, event_scheduler_thread, + (void*)scheduler_param_value)) { DBUG_PRINT("error", ("cannot create a new thread")); state= INITIALIZED; @@ -424,12 +435,12 @@ Event_scheduler::start() new_thd->proc_info= "Clearing"; DBUG_ASSERT(new_thd->net.buff != 0); net_end(&new_thd->net); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; + dec_thread_running(); delete new_thd; - pthread_cond_broadcast(&COND_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); } end: UNLOCK_DATA(); @@ -496,8 +507,8 @@ Event_scheduler::run(THD *thd) deinit_event_thread(thd); scheduler_thd= NULL; state= INITIALIZED; - DBUG_PRINT("info", ("Signalling back to the stopper COND_state")); - pthread_cond_signal(&COND_state); + DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers")); + mysql_cond_broadcast(&COND_state); UNLOCK_DATA(); DBUG_RETURN(res); @@ -541,8 +552,9 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) reasonable level. */ /* Major failure */ - if ((res= pthread_create(&th, &connection_attrib, event_worker_thread, - event_name))) + if ((res= mysql_thread_create(key_thread_event_worker, + &th, &connection_attrib, event_worker_thread, + event_name))) goto error; ++started_events; @@ -557,12 +569,12 @@ error: new_thd->proc_info= "Clearing"; DBUG_ASSERT(new_thd->net.buff != 0); net_end(&new_thd->net); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; + dec_thread_running(); delete new_thd; - pthread_cond_broadcast(&COND_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); } delete event_name; DBUG_RETURN(TRUE); @@ -615,7 +627,12 @@ Event_scheduler::stop() LOCK_DATA(); DBUG_PRINT("info", ("state before action %s", scheduler_states_names[state].str)); if (state != RUNNING) + { + /* Synchronously wait until the scheduler stops. */ + while (state != INITIALIZED) + COND_STATE_WAIT(thd, NULL, "Waiting for the scheduler to stop"); goto end; + } /* Guarantee we don't catch spurious signals */ do { @@ -637,13 +654,13 @@ Event_scheduler::stop() DBUG_PRINT("info", ("Scheduler thread has id %lu", scheduler_thd->thread_id)); /* Lock from delete */ - pthread_mutex_lock(&scheduler_thd->LOCK_thd_data); + mysql_mutex_lock(&scheduler_thd->LOCK_thd_data); /* This will wake up the thread if it waits on Queue's conditional */ sql_print_information("Event Scheduler: Killing the scheduler thread, " "thread id %lu", scheduler_thd->thread_id); scheduler_thd->awake(KILL_CONNECTION); - pthread_mutex_unlock(&scheduler_thd->LOCK_thd_data); + mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data); /* thd could be 0x0, when shutting down */ sql_print_information("Event Scheduler: " @@ -679,12 +696,12 @@ Event_scheduler::workers_count() uint count= 0; DBUG_ENTER("Event_scheduler::workers_count"); - pthread_mutex_lock(&LOCK_thread_count); // For unlink from list + mysql_mutex_lock(&LOCK_thread_count); // For unlink from list I_List_iterator<THD> it(threads); while ((tmp=it++)) if (tmp->system_thread == SYSTEM_THREAD_EVENT_WORKER) ++count; - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("exit", ("%d", count)); DBUG_RETURN(count); } @@ -705,7 +722,7 @@ Event_scheduler::lock_data(const char *func, uint line) { DBUG_ENTER("Event_scheduler::lock_data"); DBUG_PRINT("enter", ("func=%s line=%u", func, line)); - pthread_mutex_lock(&LOCK_scheduler_state); + mysql_mutex_lock(&LOCK_scheduler_state); mutex_last_locked_in_func= func; mutex_last_locked_at_line= line; mutex_scheduler_data_locked= TRUE; @@ -731,18 +748,18 @@ Event_scheduler::unlock_data(const char *func, uint line) mutex_last_unlocked_at_line= line; mutex_scheduler_data_locked= FALSE; mutex_last_unlocked_in_func= func; - pthread_mutex_unlock(&LOCK_scheduler_state); + mysql_mutex_unlock(&LOCK_scheduler_state); DBUG_VOID_RETURN; } /* - Wrapper for pthread_cond_wait/timedwait + Wrapper for mysql_cond_wait/timedwait SYNOPSIS Event_scheduler::cond_wait() thd Thread (Could be NULL during shutdown procedure) - abstime If not null then call pthread_cond_timedwait() + abstime If not null then call mysql_cond_timedwait() msg Message for thd->proc_info func Which function is requesting cond_wait line On which line cond_wait is requested @@ -760,11 +777,11 @@ Event_scheduler::cond_wait(THD *thd, struct timespec *abstime, const char* msg, if (thd) thd->enter_cond(&COND_state, &LOCK_scheduler_state, msg); - DBUG_PRINT("info", ("pthread_cond_%swait", abstime? "timed":"")); + DBUG_PRINT("info", ("mysql_cond_%swait", abstime? "timed":"")); if (!abstime) - pthread_cond_wait(&COND_state, &LOCK_scheduler_state); + mysql_cond_wait(&COND_state, &LOCK_scheduler_state); else - pthread_cond_timedwait(&COND_state, &LOCK_scheduler_state, abstime); + mysql_cond_timedwait(&COND_state, &LOCK_scheduler_state, abstime); if (thd) { /* |