Two mutexes locked with separate lock_guards instead of one combined lock
ID |
c.maintainability.multiple_individual_lock_guards |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
low |
Resource |
Concurrency |
Language |
C / C++ |
Description
These two mutexes are each locked with their own std::lock_guard, one after the other. If another thread acquires the same two mutexes in the opposite order, the two threads can each hold one lock while waiting for the other, deadlocking. Acquire both together with std::scoped_lock (or std::lock), which uses a deadlock-avoidance algorithm to lock the whole set safely.
Rationale
These two mutexes are each locked with their own std::lock_guard, one after the other. If another thread acquires the same two mutexes in the opposite order, the two threads can each hold one lock while waiting for the other, deadlocking. Acquire both together with std::scoped_lock (or std::lock), which uses a deadlock-avoidance algorithm to lock the whole set safely.
The following code illustrates the pattern detected by this rule:
std::mutex m1;
std::mutex m2;
void two_separate_guards()
{
// FLAGGED: Two mutexes locked with separate lock_guards instead of one combined lock
std::lock_guard<std::mutex> g1(m1);
std::lock_guard<std::mutex> g2(m2);
}