Release LockData::dd_mutex before calling *_detected functions

Both `double_lock_detected()` and `potential_deadlock_detected()`
functions call `LogPrintf()` which in turn implies locking of the
`Logger::m_cs` mutex. To avoid a deadlock the latter must not have the
`Mutex` type.
With this change the mentioned restriction has been lifted, and it is
possible now to use our regular `Mutex` type for the `Logger::m_cs`
mutex instead of a dedicated `StdMutex` type.
This commit is contained in:
Hennadii Stepanov 2024-02-12 14:35:27 +00:00
parent e3c17112dd
commit 08cfe273dd
No known key found for this signature in database
GPG key ID: 410108112E7EA81F

View file

@ -156,7 +156,7 @@ static void push_lock(MutexType* c, const CLockLocation& locklocation)
std::is_base_of<std::recursive_mutex, MutexType>::value;
LockData& lockdata = GetLockData();
std::lock_guard<std::mutex> lock(lockdata.dd_mutex);
std::unique_lock lock{lockdata.dd_mutex};
LockStack& lock_stack = lockdata.m_lock_stacks[std::this_thread::get_id()];
lock_stack.emplace_back(c, locklocation);
@ -172,6 +172,7 @@ static void push_lock(MutexType* c, const CLockLocation& locklocation)
// same thread as that results in an undefined behavior.
auto lock_stack_copy = lock_stack;
lock_stack.pop_back();
lock.unlock();
double_lock_detected(c, lock_stack_copy);
// double_lock_detected() does not return.
}
@ -182,9 +183,11 @@ static void push_lock(MutexType* c, const CLockLocation& locklocation)
const LockPair p2 = std::make_pair(c, i.first);
if (lockdata.lockorders.count(p2)) {
auto lock_stack_copy = lock_stack;
auto lock_stack_current = lock_stack;
lock_stack.pop_back();
potential_deadlock_detected(p1, lockdata.lockorders[p2], lock_stack_copy);
auto lock_stack_previous = lockdata.lockorders[p2];
lock.unlock();
potential_deadlock_detected(p1, lock_stack_previous, lock_stack_current);
// potential_deadlock_detected() does not return.
}