List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:January 20 2010 12:31pm
Subject:bzr push into mysql-5.6-next-mr branch (kostja:3058 to 3060) Bug#38924
Bug#46272
View as plain text  
 3060 Konstantin Osipov	2010-01-20
      Bug#46272/Bug#38924 review fixes in progress.
      Introduce class MDL_map to hold all MDL locks
      taken in the server.

    modified:
      sql/mdl.cc
 3059 Konstantin Osipov	2010-01-20
      Bug#46272/Bug#38924 review fixes in progress.
      Misc fixes.

    modified:
      sql/mdl.cc
      sql/mdl.h
 3058 Konstantin Osipov	2010-01-20
      Bug#46272/Bug#38924 review fixes in progress.
      Update MDL_key class to be more compact.
      Simplify the comparison method, used when sorting MDL_keys.

    modified:
      sql/mdl.h
=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2010-01-20 10:17:29 +0000
+++ b/sql/mdl.cc	2010-01-20 12:30:49 +0000
@@ -21,6 +21,29 @@
 
 static bool mdl_initialized= 0;
 
+
+/**
+  A collection of all MDL locks. A singleton,
+  there is only one instance of the map in the server.
+  Maps MDL_key to MDL_lock instances.
+*/
+
+class MDL_map
+{
+public:
+  pthread_mutex_t m_mutex;
+  HASH m_locks;
+
+  void init();
+  void destroy();
+  MDL_lock *find(const MDL_key *key);
+  MDL_lock *find_or_insert(const MDL_key *key);
+  void remove(MDL_lock *lock);
+private:
+  bool move_from_hash_to_lock_mutex(MDL_lock *lock);
+};
+
+
 /**
   The lock context. Created internally for an acquired lock.
   For a given name, there exists only one MDL_lock instance,
@@ -78,15 +101,10 @@ public:
     return has_locks;
   }
   virtual bool can_grant_lock(const MDL_context *requestor_ctx,
-                              enum_mdl_type type, bool is_upgrade) = 0;
-  virtual void wake_up_waiters() = 0;
+                              enum_mdl_type type, bool is_upgrade)= 0;
+  virtual void wake_up_waiters()= 0;
 
   inline static MDL_lock *create(const MDL_key *key);
-  inline static void destroy(MDL_lock *lock);
-
-  static MDL_lock *find(const MDL_key *key);
-  static MDL_lock *find_or_insert(const MDL_key *key);
-  static void destroy_or_delegate_destruction(MDL_lock *lock);
 
   MDL_lock(const MDL_key *key_arg)
   : key(key_arg),
@@ -103,20 +121,21 @@ public:
   {
     pthread_mutex_destroy(&m_mutex);
   }
-private:
+  inline static void destroy(MDL_lock *lock);
+public:
   /**
     These three members are used to make it possible to separate
-    the LOCK_mdl_hash mutex and MDL_lock::m_mutex in
-    MDL_lock::find_or_insert() for increased scalability.
+    the mdl_locks.m_mutex mutex and MDL_lock::m_mutex in
+    MDL_map::find_or_insert() for increased scalability.
     The 'm_is_destroyed' member is only set by destroyers that
-    have both the LOCK_mdl_hash and MDL_lock::m_mutex, thus
+    have both the mdl_locks.m_mutex and MDL_lock::m_mutex, thus
     holding any of the mutexes is sufficient to read it.
     The 'm_ref_usage; is incremented under protection by
-    LOCK_mdl_hash, but when 'm_is_destroyed' is set to TRUE, this
+    mdl_locks.m_mutex, but when 'm_is_destroyed' is set to TRUE, this
     member is moved to be protected by the MDL_lock::m_mutex.
-    This means that the MDL_lock::find_or_insert() which only
+    This means that the MDL_map::find_or_insert() which only
     holds the MDL_lock::m_mutex can compare it to 'm_ref_release'
-    without acquiring LOCK_mdl_hash again and if equal it can also
+    without acquiring mdl_locks.m_mutex again and if equal it can also
     destroy the lock object safely.
     The 'm_ref_release' is incremented under protection by
     MDL_lock::m_mutex.
@@ -128,9 +147,6 @@ private:
   uint m_ref_usage;
   uint m_ref_release;
   bool m_is_destroyed;
-
-private:
-  static bool move_from_hash_to_lock_mutex(MDL_lock *lock);
 };
 
 
@@ -170,9 +186,7 @@ public:
 };
 
 
-static pthread_mutex_t LOCK_mdl_hash;
-static HASH mdl_locks;
-
+static MDL_map mdl_locks;
 
 extern "C"
 {
@@ -210,9 +224,7 @@ void mdl_init()
 {
   DBUG_ASSERT(! mdl_initialized);
   mdl_initialized= TRUE;
-  pthread_mutex_init(&LOCK_mdl_hash, NULL);
-  my_hash_init(&mdl_locks, &my_charset_bin, 16 /* FIXME */, 0, 0,
-               mdl_locks_key, 0, 0);
+  mdl_locks.init();
 }
 
 
@@ -228,13 +240,186 @@ void mdl_destroy()
   if (mdl_initialized)
   {
     mdl_initialized= FALSE;
-    DBUG_ASSERT(!mdl_locks.records);
-    pthread_mutex_destroy(&LOCK_mdl_hash);
-    my_hash_free(&mdl_locks);
+    mdl_locks.destroy();
   }
 }
 
 
+/** Initialize the global hash containing all MDL locks. */
+
+void MDL_map::init()
+{
+  pthread_mutex_init(&m_mutex, NULL);
+  my_hash_init(&m_locks, &my_charset_bin, 16 /* FIXME */, 0, 0,
+               mdl_locks_key, 0, 0);
+}
+
+
+/**
+  Destroy the global hash containing all MDL locks.
+  @pre It must be empty.
+*/
+
+void MDL_map::destroy()
+{
+  DBUG_ASSERT(!m_locks.records);
+  pthread_mutex_destroy(&m_mutex);
+  my_hash_free(&m_locks);
+}
+
+
+/**
+  Find MDL_lock object corresponding to the key, create it
+  if it does not exist.
+
+  @retval non-NULL - Success. MDL_lock instance for the key with
+                     locked MDL_lock::m_mutex.
+  @retval NULL     - Failure (OOM).
+*/
+
+MDL_lock* MDL_map::find_or_insert(const MDL_key *mdl_key)
+{
+  MDL_lock *lock;
+
+retry:
+  pthread_mutex_lock(&m_mutex);
+  if (!(lock= (MDL_lock*) my_hash_search(&m_locks,
+                                         mdl_key->ptr(),
+                                         mdl_key->length())))
+  {
+    lock= MDL_lock::create(mdl_key);
+    if (!lock || my_hash_insert(&m_locks, (uchar*)lock))
+    {
+      pthread_mutex_unlock(&m_mutex);
+      MDL_lock::destroy(lock);
+      return NULL;
+    }
+  }
+
+  if (move_from_hash_to_lock_mutex(lock))
+    goto retry;
+
+  return lock;
+}
+
+
+/**
+  Find MDL_lock object corresponding to the key.
+
+  @retval non-NULL - MDL_lock instance for the key with locked
+                     MDL_lock::m_mutex.
+  @retval NULL     - There was no MDL_lock for the key.
+*/
+
+MDL_lock* MDL_map::find(const MDL_key *mdl_key)
+{
+  MDL_lock *lock;
+
+retry:
+  pthread_mutex_lock(&m_mutex);
+  if (!(lock= (MDL_lock*) my_hash_search(&m_locks,
+                                         mdl_key->ptr(),
+                                         mdl_key->length())))
+  {
+    pthread_mutex_unlock(&m_mutex);
+    return NULL;
+  }
+
+  if (move_from_hash_to_lock_mutex(lock))
+    goto retry;
+
+  return lock;
+}
+
+
+/**
+  Release mdl_locks.m_mutex mutex and lock MDL_lock::m_mutex for lock
+  object from the hash. Handle situation when object was released
+  while the held no mutex.
+
+  @retval FALSE - Success.
+  @retval TRUE  - Object was released while we held no mutex, caller
+                  should re-try looking up MDL_lock object in the hash.
+*/
+
+bool MDL_map::move_from_hash_to_lock_mutex(MDL_lock *lock)
+{
+  DBUG_ASSERT(! lock->m_is_destroyed);
+  safe_mutex_assert_owner(&m_mutex);
+
+  /*
+    We increment m_ref_usage which is a reference counter protected by
+    mdl_locks.m_mutex under the condition it is present in the hash and
+    m_is_destroyed is FALSE.
+  */
+  lock->m_ref_usage++;
+  pthread_mutex_unlock(&m_mutex);
+
+  pthread_mutex_lock(&lock->m_mutex);
+  lock->m_ref_release++;
+  if (unlikely(lock->m_is_destroyed))
+  {
+    /*
+      Object was released while we held no mutex, we need to release
+      it if no others hold references to it, our reference count
+      ensured that the object as such haven't got its memory released
+      yet. We can also safely check m_ref_usage and m_ref_release to each
+      other since the object is removed from the hash so no one will
+      be able to find it and increment m_ref_usage anymore.
+    */
+    uint ref_usage= lock->m_ref_usage;
+    uint ref_release= lock->m_ref_release;
+    pthread_mutex_unlock(&lock->m_mutex);
+    if (ref_usage == ref_release)
+      MDL_lock::destroy(lock);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/**
+  Destroy MDL_lock object or delegate this resposibility to whatever thread
+  which will hold last outstanding reference to it,
+*/
+
+void MDL_map::remove(MDL_lock *lock)
+{
+  uint ref_usage, ref_release;
+
+  safe_mutex_assert_owner(&lock->m_mutex);
+
+  if (lock->cached_object)
+    (*lock->cached_object_release_hook)(lock->cached_object);
+
+  /*
+    Destroy the MDL_lock object, but ensure that anyone that is
+    holding a reference to the object is not remaining, if so he
+    has the responsibility to release it.
+
+    Setting of m_is_destroyed to TRUE while holding _both_
+    mdl_locks.m_mutex and MDL_lock::m_mutex mutexes transfers the
+    protection of m_ref_usage from mdl_locks.m_mutex to
+    MDL_lock::m_mutex while removal of object from the hash makes
+    it read-only.  Therefore whoever acquires MDL_lock::m_mutex next
+    will see most up to date version of m_ref_usage.
+
+    This means that when m_is_destroyed is TRUE and we hold the
+    MDL_lock::m_mutex we can safely read the m_ref_usage
+    member.
+  */
+  pthread_mutex_lock(&m_mutex);
+  my_hash_delete(&m_locks, (uchar*) lock);
+  lock->m_is_destroyed= TRUE;
+  ref_usage= lock->m_ref_usage;
+  ref_release= lock->m_ref_release;
+  pthread_mutex_unlock(&lock->m_mutex);
+  if (ref_usage == ref_release)
+    MDL_lock::destroy(lock);
+  pthread_mutex_unlock(&m_mutex);
+}
+
+
 /**
   Initialize a metadata locking context.
 
@@ -242,16 +427,9 @@ void mdl_destroy()
 */
 
 MDL_context::MDL_context()
+  :m_lt_or_ha_sentinel(NULL),
+  m_thd(NULL)
 {
-  m_lt_or_ha_sentinel= NULL;
-  /*
-    FIXME: In reset_n_backup_open_tables_state,
-    we abuse "init" as a reset, i.e. call it on an already
-    constructed non-empty object. This is why we can't
-    rely here on the default constructors of I_P_List
-    to empty the list.
-  */
-  m_tickets.empty();
   pthread_cond_init(&m_ctx_wakeup_cond, NULL);
 }
 
@@ -369,170 +547,22 @@ MDL_request::create(MDL_key::enum_mdl_na
 
 inline MDL_lock *MDL_lock::create(const MDL_key *mdl_key)
 {
-  if (mdl_key->mdl_namespace() == MDL_key::GLOBAL)
-    return new MDL_global_lock(mdl_key);
-  else
-    return new MDL_object_lock(mdl_key);
-}
-
-
-void MDL_lock::destroy(MDL_lock *lock)
-{
-  delete lock;
-}
-
-
-/**
-  Release LOCK_mdl_hash mutex and lock MDL_lock::m_mutex for lock
-  object from the hash. Handle situation when object was released
-  while the held no mutex.
-
-  @retval FALSE - Success.
-  @retval TRUE  - Object was released while we held no mutex, caller
-                  should re-try looking up MDL_lock object in the hash.
-*/
-
-bool MDL_lock::move_from_hash_to_lock_mutex(MDL_lock *lock)
-{
-  DBUG_ASSERT(! lock->m_is_destroyed);
-  safe_mutex_assert_owner(&LOCK_mdl_hash);
-
-  /*
-    We increment m_ref_usage which is a reference counter protected by
-    LOCK_mdl_hash under the condition it is present in the hash and
-    m_is_destroyed is FALSE.
-  */
-  lock->m_ref_usage++;
-  pthread_mutex_unlock(&LOCK_mdl_hash);
-
-  pthread_mutex_lock(&lock->m_mutex);
-  lock->m_ref_release++;
-  if (unlikely(lock->m_is_destroyed))
+  switch (mdl_key->mdl_namespace())
   {
-    /*
-      Object was released while we held no mutex, we need to release
-      it if no others hold references to it, our reference count
-      ensured that the object as such haven't got its memory released
-      yet. We can also safely check m_ref_usage and m_ref_release to each
-      other since the object is removed from the hash so no one will
-      be able to find it and increment m_ref_usage anymore.
-    */
-    uint ref_usage, ref_release;
-    ref_usage= lock->m_ref_usage;
-    ref_release= lock->m_ref_release;
-    pthread_mutex_unlock(&lock->m_mutex);
-    if (ref_usage == ref_release)
-      MDL_lock::destroy(lock);
-    return TRUE;
+    case MDL_key::GLOBAL:
+      return new MDL_global_lock(mdl_key);
+    default:
+      return new MDL_object_lock(mdl_key);
   }
-  return FALSE;
 }
 
 
-/**
-  Find MDL_lock object corresponding to the key.
-
-  @retval non-NULL - MDL_lock instance for the key with locked
-                     MDL_lock::m_mutex.
-  @retval NULL     - There was no MDL_lock for the key.
-*/
-
-MDL_lock* MDL_lock::find(const MDL_key *mdl_key)
-{
-  MDL_lock *lock;
-
-retry:
-  pthread_mutex_lock(&LOCK_mdl_hash);
-  if (!(lock= (MDL_lock*) my_hash_search(&mdl_locks,
-                                         mdl_key->ptr(),
-                                         mdl_key->length())))
-  {
-    pthread_mutex_unlock(&LOCK_mdl_hash);
-    return NULL;
-  }
-
-  if (move_from_hash_to_lock_mutex(lock))
-    goto retry;
-
-  return lock;
-}
-
-
-/**
-  Find MDL_lock object corresponding to the key, create it
-  if it does not exist.
-
-  @retval non-NULL - Success. MDL_lock instance for the key with
-                     locked MDL_lock::m_mutex.
-  @retval NULL     - Failure (OOM).
-*/
-
-MDL_lock* MDL_lock::find_or_insert(const MDL_key *mdl_key)
+void MDL_lock::destroy(MDL_lock *lock)
 {
-  MDL_lock *lock;
-
-retry:
-  pthread_mutex_lock(&LOCK_mdl_hash);
-  if (!(lock= (MDL_lock*) my_hash_search(&mdl_locks,
-                                         mdl_key->ptr(),
-                                         mdl_key->length())))
-  {
-    lock= MDL_lock::create(mdl_key);
-    if (!lock || my_hash_insert(&mdl_locks, (uchar*)lock))
-    {
-      pthread_mutex_unlock(&LOCK_mdl_hash);
-      MDL_lock::destroy(lock);
-      return NULL;
-    }
-  }
-
-  if (move_from_hash_to_lock_mutex(lock))
-    goto retry;
-
-  return lock;
+  delete lock;
 }
 
 
-/**
-  Destroy MDL_lock object or delegate this resposibility to whatever thread
-  which will hold last outstanding reference to it,
-*/
-
-void MDL_lock::destroy_or_delegate_destruction(MDL_lock *lock)
-{
-  uint ref_usage, ref_release;
-
-  safe_mutex_assert_owner(&lock->m_mutex);
-
-  if (lock->cached_object)
-    (*lock->cached_object_release_hook)(lock->cached_object);
-
-  /*
-    Destroy the MDL_lock object, but ensure that anyone that is
-    holding a reference to the object is not remaining, if so he
-    has the responsibility to release it.
-
-    Setting of m_is_destroyed to TRUE while holding _both_
-    LOCK_mdl_hash and MDL_lock::m_mutex mutexes transfers the
-    protection of m_ref_usage from LOCK_mdl_hash to
-    MDL_lock::m_mutex while removal of object from the hash makes
-    it read-only.  Therefore whoever acquires MDL_lock::m_mutex next
-    will see most up to date version of m_ref_usage.
-
-    This means that when m_is_destroyed is TRUE and we hold the
-    MDL_lock::m_mutex we can safely read the m_ref_usage
-    member.
-  */
-  pthread_mutex_lock(&LOCK_mdl_hash);
-  my_hash_delete(&mdl_locks, (uchar *)lock);
-  lock->m_is_destroyed= TRUE;
-  ref_usage= lock->m_ref_usage;
-  ref_release= lock->m_ref_release;
-  pthread_mutex_unlock(&lock->m_mutex);
-  if (ref_usage == ref_release)
-    MDL_lock::destroy(lock);
-  pthread_mutex_unlock(&LOCK_mdl_hash);
-}
 
 
 /**
@@ -693,29 +723,32 @@ MDL_global_lock::can_grant_lock(const MD
 
 
 /**
-  Wake up contexts which are waiting to acquire global metadata and
-  which may succeed now, when we released global lock or removed request
-  for global shared lock from waiters list (the latter can happen when
-  context trying to acquire global shared lock is killed).
+  Wake up contexts which are waiting to acquire the global
+  metadata lock and which may succeed now, when we released it, or
+  removed a blocking request for it from the waiters list.
+  The latter can happen when the context trying to acquire the
+  global shared lock is killed.
 */
 
 void MDL_global_lock::wake_up_waiters()
 {
   /*
-    There are no active locks or they are of INTENION EXCLUSIVE type.
-    Wake up contexts waiting for INTENTION EXCLUSIVE lock if there
-    are no pending requests for global SHARED lock.
-    (Happens when we release global SHARED lock or abort wait for
-     global SHARED lock).
+    If there are no active locks or they are of INTENTION
+    EXCLUSIVE type and there are no pending requests for global
+    SHARED lock, wake up contexts waiting for an INTENTION
+    EXCLUSIVE lock.
+    This happens when we release the global SHARED lock or abort
+    or remove a pending request for it, i.e. abort the
+    context waiting for it.
   */
   if ((granted.is_empty() ||
        granted.front()->m_type == MDL_INTENTION_EXCLUSIVE) &&
       waiting_shared.is_empty() && ! waiting_exclusive.is_empty())
   {
     MDL_lock::Ticket_iterator it(waiting_exclusive);
-    MDL_ticket *wake_up_ticket;
-    while ((wake_up_ticket= it++))
-      wake_up_ticket->get_ctx()->wake_up();
+    MDL_ticket *awake_ticket;
+    while ((awake_ticket= it++))
+      awake_ticket->get_ctx()->awake();
   }
 
   /*
@@ -732,9 +765,9 @@ void MDL_global_lock::wake_up_waiters()
       ! waiting_shared.is_empty())
   {
     MDL_lock::Ticket_iterator it(waiting_shared);
-    MDL_ticket *wake_up_ticket;
-    while ((wake_up_ticket= it++))
-      wake_up_ticket->get_ctx()->wake_up();
+    MDL_ticket *awake_ticket;
+    while ((awake_ticket= it++))
+      awake_ticket->get_ctx()->awake();
   }
 }
 
@@ -864,7 +897,7 @@ void MDL_object_lock::wake_up_waiters()
     MDL_lock::Ticket_iterator it(waiting_shared);
     MDL_ticket *waiting_ticket;
     while ((waiting_ticket= it++))
-      waiting_ticket->get_ctx()->wake_up();
+      waiting_ticket->get_ctx()->awake();
   }
 
   /*
@@ -876,7 +909,7 @@ void MDL_object_lock::wake_up_waiters()
     MDL_lock::Ticket_iterator it(waiting_exclusive);
     MDL_ticket *waiting_ticket;
     while ((waiting_ticket= it++))
-      waiting_ticket->get_ctx()->wake_up();
+      waiting_ticket->get_ctx()->awake();
   }
 }
 
@@ -989,7 +1022,7 @@ MDL_context::acquire_lock_impl(MDL_reque
     return TRUE;
 
   /* The below call also implicitly locks MDL_lock::m_mutex. */
-  if (! (lock= MDL_lock::find_or_insert(key)))
+  if (! (lock= mdl_locks.find_or_insert(key)))
   {
     MDL_ticket::destroy(ticket);
     return TRUE;
@@ -1028,7 +1061,7 @@ MDL_context::acquire_lock_impl(MDL_reque
       else
         lock->waiting_exclusive.remove(ticket);
       if (lock->is_empty())
-        MDL_lock::destroy_or_delegate_destruction(lock);
+        mdl_locks.remove(lock);
       else
       {
         lock->wake_up_waiters();
@@ -1159,7 +1192,7 @@ MDL_context::try_acquire_lock_impl(MDL_r
     return TRUE;
 
   /* The below call also implicitly locks MDL_lock::m_mutex. */
-  if (!(lock= MDL_lock::find_or_insert(key)))
+  if (!(lock= mdl_locks.find_or_insert(key)))
   {
     MDL_ticket::destroy(ticket);
     return TRUE;
@@ -1276,9 +1309,9 @@ void notify_shared_lock(THD *thd, MDL_ti
 
     /*
       If the thread that holds the conflicting lock is waiting in MDL
-      subsystem it has to be woken up by calling MDL_context::wake_up().
+      subsystem it has to be woken up by calling MDL_context::awake().
     */
-    conflicting_ticket->get_ctx()->wake_up();
+    conflicting_ticket->get_ctx()->awake();
     /*
       If it is waiting on table-level lock or some other non-MDL resource
       we delegate its waking up to code outside of MDL.
@@ -1338,7 +1371,7 @@ bool MDL_context::acquire_exclusive_lock
     return TRUE;
 
   /* The below call also implicitly locks MDL_lock::m_mutex. */
-  if (!(lock= MDL_lock::find_or_insert(key)))
+  if (!(lock= mdl_locks.find_or_insert(key)))
   {
     MDL_ticket::destroy(ticket);
     return TRUE;
@@ -1368,7 +1401,7 @@ bool MDL_context::acquire_exclusive_lock
       /* Get rid of pending ticket. */
       lock->waiting_exclusive.remove(ticket);
       if (lock->is_empty())
-        MDL_lock::destroy_or_delegate_destruction(lock);
+        mdl_locks.remove(lock);
       else
       {
         /*
@@ -1422,7 +1455,7 @@ bool MDL_context::acquire_exclusive_lock
       /* Get rid of pending ticket. */
       lock->waiting_exclusive.remove(ticket);
       if (lock->is_empty())
-        MDL_lock::destroy_or_delegate_destruction(lock);
+        mdl_locks.remove(lock);
       else
       {
         /*
@@ -1894,7 +1927,7 @@ MDL_context::wait_for_locks(MDL_request_
           mdl_request->type == MDL_INTENTION_EXCLUSIVE)
       {
         /* The below call also implicitly locks MDL_lock::m_mutex. */
-        if (! (lock= MDL_lock::find(key)))
+        if (! (lock= mdl_locks.find(key)))
           continue;
 
         if (lock->can_grant_lock(this, mdl_request->type, FALSE))
@@ -1932,7 +1965,7 @@ MDL_context::wait_for_locks(MDL_request_
         else
           lock->waiting_exclusive.remove(pending_ticket);
         if (lock->is_empty())
-          MDL_lock::destroy_or_delegate_destruction(lock);
+          mdl_locks.remove(lock);
         else
           pthread_mutex_unlock(&lock->m_mutex);
         MDL_ticket::destroy(pending_ticket);
@@ -1973,7 +2006,7 @@ void MDL_context::release_lock(MDL_ticke
   lock->granted.remove(ticket);
 
   if (lock->is_empty())
-    MDL_lock::destroy_or_delegate_destruction(lock);
+    mdl_locks.remove(lock);
   else
   {
     lock->wake_up_waiters();
@@ -2078,7 +2111,7 @@ void MDL_ticket::downgrade_exclusive_loc
     MDL_lock::Ticket_iterator it(m_lock->waiting_shared);
     MDL_ticket *ticket;
     while ((ticket= it++))
-      ticket->get_ctx()->wake_up();
+      ticket->get_ctx()->awake();
   }
 
   pthread_mutex_unlock(&m_lock->m_mutex);

=== modified file 'sql/mdl.h'
--- a/sql/mdl.h	2010-01-20 10:40:14 +0000
+++ b/sql/mdl.h	2010-01-20 11:19:31 +0000
@@ -316,7 +316,6 @@ private:
      m_lock(NULL)
   {}
 
-
   static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg);
   static void destroy(MDL_ticket *ticket);
 private:
@@ -420,7 +419,7 @@ public:
   /**
     Wake up context which is waiting for a change of MDL_lock state.
   */
-  void wake_up()
+  void awake()
   {
     pthread_cond_signal(&m_ctx_wakeup_cond);
   }


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100120123049-p2uo244b4rfpn2i8.bundle
Thread
bzr push into mysql-5.6-next-mr branch (kostja:3058 to 3060) Bug#38924Bug#46272Konstantin Osipov20 Jan