MWL#182: Explain running statements: address review feedback
- Add Monty Program Ab copyright in new files - Change Apc_target::make_apc_call() to accept a C++-style functor (instead of C-style function + parameter)
This commit is contained in:
parent
66c62de103
commit
c62c0c5516
@ -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
|
||||
|
30
sql/my_apc.h
30
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user