summaryrefslogtreecommitdiff
path: root/sql/mdl.cc
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@skysql.com>2014-05-21 11:09:55 -0400
committerNirbhay Choubey <nirbhay@skysql.com>2014-05-21 11:09:55 -0400
commit086af8367ed2499adae378638225ceb14c85f046 (patch)
tree953720d86a4decd67a24b560ffbe277900ff9609 /sql/mdl.cc
parent558995ad84ca1348dfe681a8d111650225fcc205 (diff)
parent1170a54060168d885cbf682836342d4fc4ccae1a (diff)
downloadmariadb-git-086af8367ed2499adae378638225ceb14c85f046.tar.gz
bzr merge -r4209 maria/10.0.
Diffstat (limited to 'sql/mdl.cc')
-rw-r--r--sql/mdl.cc37
1 files changed, 34 insertions, 3 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 8360243b4da..5755b2bbfd5 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -730,6 +730,7 @@ static inline int mdl_iterate_lock(MDL_lock *lock,
int mdl_iterate(int (*callback)(MDL_ticket *ticket, void *arg), void *arg)
{
+ DYNAMIC_ARRAY locks;
uint i, j;
int res;
DBUG_ENTER("mdl_iterate");
@@ -738,18 +739,48 @@ int mdl_iterate(int (*callback)(MDL_ticket *ticket, void *arg), void *arg)
(res= mdl_iterate_lock(mdl_locks.m_commit_lock, callback, arg)))
DBUG_RETURN(res);
+ my_init_dynamic_array(&locks, sizeof(MDL_lock*), 512, 1, MYF(0));
+
for (i= 0; i < mdl_locks.m_partitions.elements(); i++)
{
MDL_map_partition *part= mdl_locks.m_partitions.at(i);
+ /* Collect all locks first */
mysql_mutex_lock(&part->m_mutex);
+ if (allocate_dynamic(&locks, part->m_locks.records))
+ {
+ res= 1;
+ mysql_mutex_unlock(&part->m_mutex);
+ break;
+ }
+ reset_dynamic(&locks);
for (j= 0; j < part->m_locks.records; j++)
{
- if ((res= mdl_iterate_lock((MDL_lock*) my_hash_element(&part->m_locks, j),
- callback, arg)))
- break;
+ MDL_lock *lock= (MDL_lock*) my_hash_element(&part->m_locks, j);
+ lock->m_ref_usage++;
+ insert_dynamic(&locks, &lock);
}
mysql_mutex_unlock(&part->m_mutex);
+
+ /* Now show them */
+ for (j= 0; j < locks.elements; j++)
+ {
+ MDL_lock *lock= (MDL_lock*) *dynamic_element(&locks, j, MDL_lock**);
+ res= mdl_iterate_lock(lock, callback, arg);
+
+ mysql_prlock_wrlock(&lock->m_rwlock);
+ uint ref_usage= lock->m_ref_usage;
+ uint ref_release= ++lock->m_ref_release;
+ bool is_destroyed= lock->m_is_destroyed;
+ mysql_prlock_unlock(&lock->m_rwlock);
+
+ if (unlikely(is_destroyed && ref_usage == ref_release))
+ MDL_lock::destroy(lock);
+
+ if (res)
+ break;
+ }
}
+ delete_dynamic(&locks);
DBUG_RETURN(res);
}