diff --git a/sql/my_apc.cc b/sql/my_apc.cc index eae2843edb4..212fbd0f6cb 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -1,6 +1,18 @@ /* - TODO: MP AB Copyright -*/ + Copyright (c) 2009, 2011, Monty Program Ab + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 */ #ifdef MY_APC_STANDALONE @@ -139,8 +151,8 @@ void Apc_target::dequeue_request(Call_request *qe) to use thd->enter_cond() calls to be killable) */ -bool Apc_target::make_apc_call(apc_func_t func, void *func_arg, - int timeout_sec, bool *timed_out) +bool Apc_target::make_apc_call(Apc_call *call, int timeout_sec, + bool *timed_out) { bool res= TRUE; *timed_out= FALSE; @@ -149,8 +161,7 @@ bool Apc_target::make_apc_call(apc_func_t func, void *func_arg, { /* Create and post the request */ Call_request apc_request; - apc_request.func= func; - apc_request.func_arg= func_arg; + apc_request.call= call; apc_request.processed= FALSE; mysql_cond_init(0 /* do not track in PS */, &apc_request.COND_request, NULL); enqueue_request(&apc_request); @@ -229,7 +240,7 @@ void Apc_target::process_apc_requests() dequeue_request(request); request->processed= TRUE; - request->func(request->func_arg); + request->call->call_in_target_thread(); request->what="func called by process_apc_requests"; #ifndef DBUG_OFF diff --git a/sql/my_apc.h b/sql/my_apc.h index 450e07b92a4..3d9a2154af2 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -1,6 +1,18 @@ /* - TODO: MP AB Copyright -*/ + Copyright (c) 2009, 2011, Monty Program Ab + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 */ /* Interface @@ -38,8 +50,12 @@ public: void process_apc_requests(); - typedef void (*apc_func_t)(void *arg); - + class Apc_call + { + public: + virtual void call_in_target_thread()= 0; + virtual ~Apc_call() {} + }; /* Make an APC call: schedule it for execution and wait until the target thread has executed it. This function must not be called from a thread @@ -49,8 +65,7 @@ public: @retval TRUE - Call wasnt made (either the target is in disabled state or timeout occured) */ - bool make_apc_call(apc_func_t func, void *func_arg, - int timeout_sec, bool *timed_out); + bool make_apc_call(Apc_call *call, int timeout_sec, bool *timed_out); #ifndef DBUG_OFF int n_calls_processed; /* Number of calls served by this target */ @@ -78,8 +93,7 @@ private: class Call_request { public: - apc_func_t func; /* Function to call */ - void *func_arg; /* Argument to pass it */ + Apc_call *call; /* Functor to be called */ /* The caller will actually wait for "processed==TRUE" */ bool processed; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5408b10c6b1..35cc28bcae7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3330,33 +3330,32 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup) we're producing EXPLAIN for. */ -void Show_explain_request::get_explain_data(void *arg) +void Show_explain_request::call_in_target_thread() { - Show_explain_request *req= (Show_explain_request*)arg; Query_arena backup_arena; - THD *target_thd= req->target_thd; bool printed_anything= FALSE; /* Change the arena because JOIN::print_explain and co. are going to allocate items. Let them allocate them on our arena. */ - target_thd->set_n_backup_active_arena((Query_arena*)req->request_thd, + target_thd->set_n_backup_active_arena((Query_arena*)request_thd, &backup_arena); - req->query_str.copy(target_thd->query(), - target_thd->query_length(), - &my_charset_bin); + query_str.copy(target_thd->query(), + target_thd->query_length(), + &my_charset_bin); - if (target_thd->lex->unit.print_explain(req->explain_buf, 0 /* explain flags*/, + if (target_thd->lex->unit.print_explain(explain_buf, 0 /* explain flags*/, &printed_anything)) - req->failed_to_produce= TRUE; + { + failed_to_produce= TRUE; + } if (!printed_anything) - req->failed_to_produce= TRUE; + failed_to_produce= TRUE; - target_thd->restore_active_arena((Query_arena*)req->request_thd, - &backup_arena); + target_thd->restore_active_arena((Query_arena*)request_thd, &backup_arena); } diff --git a/sql/sql_class.h b/sql/sql_class.h index bfbc9e86611..73123151738 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1528,11 +1528,11 @@ class select_result_explain_buffer; The thread that runs SHOW EXPLAIN statement creates a Show_explain_request object R, and then schedules APC call of - Show_explain_request::get_explain_data((void*)&R). + Show_explain_request::call((void*)&R). */ -class Show_explain_request +class Show_explain_request : public Apc_target::Apc_call { public: THD *target_thd; /* thd that we're running SHOW EXPLAIN for */ @@ -1546,8 +1546,9 @@ public: /* Query that we've got SHOW EXPLAIN for */ String query_str; - - static void get_explain_data(void *arg); + + /* Overloaded virtual function */ + void call_in_target_thread(); }; class THD; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0671ebae199..145f4fbebcc 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2065,9 +2065,7 @@ void mysqld_show_explain(THD *thd, ulong thread_id) explain_req.failed_to_produce= FALSE; /* Ok, we have a lock on target->LOCK_thd_data, can call: */ - bres= tmp->apc_target.make_apc_call(Show_explain_request::get_explain_data, - (void*)&explain_req, - timeout_sec, &timed_out); + bres= tmp->apc_target.make_apc_call(&explain_req, timeout_sec, &timed_out); if (bres || explain_req.failed_to_produce) {