diff options
author | Nirbhay Choubey <nirbhay@skysql.com> | 2014-05-21 11:09:55 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@skysql.com> | 2014-05-21 11:09:55 -0400 |
commit | 086af8367ed2499adae378638225ceb14c85f046 (patch) | |
tree | 953720d86a4decd67a24b560ffbe277900ff9609 /sql/mdl.cc | |
parent | 558995ad84ca1348dfe681a8d111650225fcc205 (diff) | |
parent | 1170a54060168d885cbf682836342d4fc4ccae1a (diff) | |
download | mariadb-git-086af8367ed2499adae378638225ceb14c85f046.tar.gz |
bzr merge -r4209 maria/10.0.
Diffstat (limited to 'sql/mdl.cc')
-rw-r--r-- | sql/mdl.cc | 37 |
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); } |