2801 Davi Arnaut 2009-02-12
WL#4284: Transactional DDL locking
Preparing for removing requests from the MDL subsystem.
Remove reference counting by detaching requests from tickets.
modified:
sql/mdl.cc
sql/mdl.h
2800 Konstantin Osipov 2009-02-11
WL#4284 "Transactional DDL locking"
Review comments.
Remove request from MDL_LOCK. A step on the path of removing
requests from the MDL subsystem completely (they only need
to be used to add a ticket).
Move enum mdl_state to MDL_LOCK_TICKET. Simplify the state:
a ticket can be either pending, or acquired.
modified:
sql/mdl.cc
sql/mdl.h
=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc 2009-02-10 22:38:38 +0000
+++ b/sql/mdl.cc 2009-02-12 22:00:31 +0000
@@ -765,7 +765,7 @@ bool mdl_acquire_shared_lock(MDL_CONTEXT
/*
Check whether the context already holds a shared lock on the object,
- and if so, bump the ticket reference count and grant the request.
+ and if so, grant the request.
*/
if ((ticket= mdl_context_find_ticket(context, lock_req)))
{
@@ -1306,34 +1306,6 @@ bool mdl_wait_for_locks(MDL_CONTEXT *con
/**
- Decrement the reference count for a lock ticket. If the reference
- count reaches zero, a provided release callback is called.
-
- @param ticket The lock ticket whose reference count should be decremented.
- @param release Callback function that performs the ticket release.
-
- @return TRUE if the ticket was released, otherwise FALSE.
-*/
-
-typedef void (ticket_release_t)(MDL_CONTEXT *, MDL_LOCK_TICKET *);
-
-static inline bool ticket_unref(MDL_LOCK_TICKET *ticket,
- ticket_release_t *release)
-{
- if (ticket->count == 1)
- {
- release(ticket->ctx, ticket);
- return TRUE;
- }
- else
- {
- ticket->count--;
- return FALSE;
- }
-}
-
-
-/**
Auxiliary function which allows to release particular lock
ownership of which is represented by a lock ticket object.
*/
@@ -1347,8 +1319,6 @@ static void release_ticket(MDL_CONTEXT *
safe_mutex_assert_owner(&LOCK_mdl);
- DBUG_ASSERT(ticket->count == 1);
-
context->tickets.remove(ticket);
switch (ticket->type)
@@ -1386,21 +1356,6 @@ static void release_ticket(MDL_CONTEXT *
/**
- Wrapper function which takes LOCK_mdl before releasing a lock ticket.
-*/
-
-static void release_ticket_wrapper(MDL_CONTEXT *context, MDL_LOCK_TICKET *ticket)
-{
- safe_mutex_assert_not_owner(&LOCK_open);
-
- pthread_mutex_lock(&LOCK_mdl);
- release_ticket(context, ticket);
- pthread_cond_broadcast(&COND_mdl);
- pthread_mutex_unlock(&LOCK_mdl);
-}
-
-
-/**
Release all locks associated with the context, but leave them
in the context as lock requests.
@@ -1414,36 +1369,36 @@ static void release_ticket_wrapper(MDL_C
void mdl_ticket_release_all(MDL_CONTEXT *context)
{
- MDL_LOCK_REQUEST *lock_req;
- MDL_CONTEXT::Request_iterator it(context->requests);
+ MDL_LOCK_TICKET *ticket;
+ MDL_CONTEXT::Ticket_iterator it(context->tickets);
DBUG_ENTER("mdl_ticket_release_all");
safe_mutex_assert_not_owner(&LOCK_open);
- pthread_mutex_lock(&LOCK_mdl);
- while ((lock_req= it++))
+ /* Detach lock tickets from the requests for back off. */
{
- DBUG_PRINT("info", ("found lock to release lock_req=%p", lock_req));
- /*
- Don't call release_lock() for a shared lock if has not been
- granted. We have pending and granted shared locks in the
- same context when this function is called from the "back-off"
- path of open_tables().
- */
- if (lock_req->ticket != NULL)
- {
- ticket_unref(lock_req->ticket, release_ticket);
+ MDL_LOCK_REQUEST *lock_req;
+ MDL_CONTEXT::Request_iterator it(context->requests);
+
+ while ((lock_req= it++))
lock_req->ticket= NULL;
- }
- /*
- We will return lock request to its initial state only in
- mdl_request_remove_all() since we need to know type of lock
- request in mdl_wait_for_locks().
- */
+ }
+
+ if (context->tickets.is_empty())
+ DBUG_VOID_RETURN;
+
+ pthread_mutex_lock(&LOCK_mdl);
+ while ((ticket= it++))
+ {
+ DBUG_PRINT("info", ("found lock to release ticket=%p", ticket));
+ release_ticket(context, ticket);
}
/* Inefficient but will do for a while */
pthread_cond_broadcast(&COND_mdl);
pthread_mutex_unlock(&LOCK_mdl);
+
+ context->tickets.empty();
+
DBUG_VOID_RETURN;
}
@@ -1459,7 +1414,12 @@ void mdl_ticket_release_all(MDL_CONTEXT
void mdl_ticket_release(MDL_CONTEXT *context, MDL_LOCK_TICKET *ticket)
{
DBUG_ASSERT(context == ticket->ctx);
- ticket_unref(ticket, release_ticket_wrapper);
+ safe_mutex_assert_not_owner(&LOCK_open);
+
+ pthread_mutex_lock(&LOCK_mdl);
+ release_ticket(context, ticket);
+ pthread_cond_broadcast(&COND_mdl);
+ pthread_mutex_unlock(&LOCK_mdl);
}
@@ -1493,10 +1453,18 @@ void mdl_ticket_release_all_for_name(MDL
{
DBUG_ASSERT(lock_req->ticket && lock_req->ticket->state == MDL_ACQUIRED);
if (lock_req->ticket->lock == lock)
- {
- mdl_ticket_release(context, lock_req->ticket);
mdl_request_remove(context, lock_req);
- }
+ }
+
+ /* Remove matching lock tickets from the context. */
+ MDL_LOCK_TICKET *lock_tkt;
+ MDL_CONTEXT::Ticket_iterator it_lock_tkt(context->tickets);
+
+ while ((lock_tkt= it_lock_tkt++))
+ {
+ DBUG_ASSERT(lock_tkt->state == MDL_ACQUIRED);
+ if (lock_tkt->lock == lock)
+ mdl_ticket_release(context, lock_tkt);
}
}
=== modified file 'sql/mdl.h'
--- a/sql/mdl.h 2009-02-10 22:38:38 +0000
+++ b/sql/mdl.h 2009-02-12 22:00:31 +0000
@@ -195,6 +195,14 @@ struct MDL_LOCK_TICKET
struct MDL_CONTEXT
{
+ typedef I_P_List<MDL_LOCK_REQUEST,
+ I_P_List_adapter<MDL_LOCK_REQUEST,
+ &MDL_LOCK_REQUEST::next_in_context,
+ &MDL_LOCK_REQUEST::prev_in_context> >
+ Request_list;
+
+ typedef Request_list::Iterator Request_iterator;
+
typedef I_P_List<MDL_LOCK_TICKET,
I_P_List_adapter<MDL_LOCK_TICKET,
&MDL_LOCK_TICKET::next_in_context,
@@ -203,8 +211,8 @@ struct MDL_CONTEXT
typedef Ticket_list::Iterator Ticket_iterator;
- Ticket_list pending;
- Ticket_list granted;
+ Request_list requests;
+ Ticket_list tickets;
bool has_global_shared_lock;
THD *thd;
};
@@ -224,6 +232,8 @@ void mdl_request_init(MDL_LOCK_REQUEST *
MDL_LOCK_REQUEST *mdl_request_alloc(unsigned char type, const char *db,
const char *name, MEM_ROOT *root);
void mdl_request_add(MDL_CONTEXT *context, MDL_LOCK_REQUEST *lock_req);
+void mdl_request_remove(MDL_CONTEXT *context, MDL_LOCK_REQUEST *lock_req);
+void mdl_request_remove_all(MDL_CONTEXT *context);
/**
Set type of lock request. Can be only applied to pending locks.
| Thread |
|---|
| • bzr push into mysql-6.0-runtime branch (davi:2800 to 2801) WL#4284 | Davi Arnaut | 12 Feb |