summaryrefslogtreecommitdiff
path: root/sql/my_apc.h
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2012-06-07 12:19:06 +0400
committerSergey Petrunya <psergey@askmonty.org>2012-06-07 12:19:06 +0400
commit2c1e737c6c955ef6e670514d3bd9031727f3602c (patch)
tree0d97958460420a3b2633eb9fb6a2d57b2405e9fb /sql/my_apc.h
parent9a7b3bf4b7b08f9fd1d26260131696475998ab81 (diff)
downloadmariadb-git-2c1e737c6c955ef6e670514d3bd9031727f3602c.tar.gz
MDEV-297: SHOW EXPLAIN: Server gets stuck until timeout occurs while executing SHOW
INDEX and SHOW EXPLAIN in parallel - Rework locking code to use the LOCK_thd_data mutex for all synchronization. This also fixed MDEV-301.
Diffstat (limited to 'sql/my_apc.h')
-rw-r--r--sql/my_apc.h39
1 files changed, 30 insertions, 9 deletions
diff --git a/sql/my_apc.h b/sql/my_apc.h
index 0698703ad40..8e6980fa855 100644
--- a/sql/my_apc.h
+++ b/sql/my_apc.h
@@ -22,15 +22,16 @@
*/
/*
- Target for asynchronous calls.
+ Target for asynchronous procedue calls (APCs).
*/
class Apc_target
{
+ mysql_mutex_t *LOCK_thd_data_ptr;
public:
Apc_target() : enabled(0), apc_calls(NULL) /*, call_queue_size(0)*/ {}
~Apc_target() { DBUG_ASSERT(!enabled && !apc_calls);}
- void init();
+ void init(mysql_mutex_t *target_mutex);
void destroy();
void enable();
void disable();
@@ -68,14 +69,31 @@ private:
/*
Circular, double-linked list of all enqueued call requests.
We use this structure, because we
- - process requests sequentially
+ - process requests sequentially (i.e. they are removed from the front)
- a thread that has posted a request may time out (or be KILLed) and
- cancel the request, which means we'll need to remove its request at
- arbitrary point in time.
+ cancel the request, which means we need a fast request-removal
+ operation.
*/
Call_request *apc_calls;
+
- pthread_mutex_t LOCK_apc_queue;
+ /*
+ This mutex is used to
+ - make queue put/remove operations atomic (one must be in posession of the
+ mutex when putting/removing something from the queue)
+
+ - make sure that nobody enqueues a request onto an Apc_target which has
+ disabled==TRUE. The idea is:
+ = requestor must be in possession of the mutex and check that
+ disabled==FALSE when he is putting his request into the queue.
+ = When the owner (ie. service) thread changes the Apc_target from
+ enabled to disabled, it will acquire the mutex, disable the
+ Apc_target (preventing any new requests), and then serve all pending
+ requests.
+ That way, we will never have the situation where the Apc_target is
+ disabled, but there are some un-served requests.
+ */
+ //pthread_mutex_t LOCK_apc_queue;
class Call_request
{
@@ -84,13 +102,16 @@ private:
void *func_arg; /* Argument to pass it */
bool processed;
- pthread_mutex_t LOCK_request;
- pthread_cond_t COND_request;
+ //pthread_mutex_t LOCK_request;
+ //pthread_cond_t COND_request;
+
+ /* Condition that will be signalled when the request has been served */
+ mysql_cond_t COND_request;
Call_request *next;
Call_request *prev;
- const char *what; /* State of the request */
+ const char *what; /* (debug) state of the request */
};
void enqueue_request(Call_request *qe);