MDL_lock encapsulation: MDL_lock::iterate()
Avoid accessing MDL_lock::m_waiting, MDL_lock::m_granted and MDL_lock::m_rwlock from mdl_iterate_lock(), use MDL_lock::iterate() instead. This is part of broader cleanup, which aims to make large part of MDL_lock members private. It is needed to simplify further work on MDEV-19749 - MDL scalability regression after backup locks.
This commit is contained in:
parent
8d0ccd911f
commit
0556a46caa
45
sql/mdl.cc
45
sql/mdl.cc
@ -707,6 +707,35 @@ public:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Callback for mdl_iterate()
|
||||||
|
|
||||||
|
Another thread may be deleting this MDL_lock concurrently.
|
||||||
|
Being deleted lock can still be iterated since it must have
|
||||||
|
valid empty granted/waiting lists.
|
||||||
|
*/
|
||||||
|
bool iterate(mdl_iterator_callback callback, void *argument)
|
||||||
|
{
|
||||||
|
bool res= true;
|
||||||
|
mysql_prlock_rdlock(&m_rwlock);
|
||||||
|
DBUG_ASSERT(m_strategy || is_empty());
|
||||||
|
for (MDL_ticket &ticket : m_granted)
|
||||||
|
{
|
||||||
|
if (callback(&ticket, argument, true))
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
for (MDL_ticket &ticket : m_waiting)
|
||||||
|
{
|
||||||
|
if (callback(&ticket, argument, false))
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
res= false;
|
||||||
|
end:
|
||||||
|
mysql_prlock_unlock(&m_rwlock);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
const MDL_lock_strategy *m_strategy;
|
const MDL_lock_strategy *m_strategy;
|
||||||
private:
|
private:
|
||||||
static const MDL_backup_lock m_backup_lock_strategy;
|
static const MDL_backup_lock m_backup_lock_strategy;
|
||||||
@ -787,21 +816,7 @@ static my_bool mdl_iterate_lock(void *lk, void *a)
|
|||||||
{
|
{
|
||||||
MDL_lock *lock= static_cast<MDL_lock*>(lk);
|
MDL_lock *lock= static_cast<MDL_lock*>(lk);
|
||||||
mdl_iterate_arg *arg= static_cast<mdl_iterate_arg*>(a);
|
mdl_iterate_arg *arg= static_cast<mdl_iterate_arg*>(a);
|
||||||
/*
|
return lock->iterate(arg->callback, arg->argument);
|
||||||
We can skip check for m_strategy here, becase m_granted
|
|
||||||
must be empty for such locks anyway.
|
|
||||||
*/
|
|
||||||
mysql_prlock_rdlock(&lock->m_rwlock);
|
|
||||||
bool res= std::any_of(lock->m_granted.begin(), lock->m_granted.end(),
|
|
||||||
[arg](MDL_ticket &ticket) {
|
|
||||||
return arg->callback(&ticket, arg->argument, true);
|
|
||||||
});
|
|
||||||
res= std::any_of(lock->m_waiting.begin(), lock->m_waiting.end(),
|
|
||||||
[arg](MDL_ticket &ticket) {
|
|
||||||
return arg->callback(&ticket, arg->argument, false);
|
|
||||||
});
|
|
||||||
mysql_prlock_unlock(&lock->m_rwlock);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user