CERT.CONC.MUTEX.DESTROY_WHILE_LOCKED
Do not destroy a mutex while it is locked.
Mutex objects are used to protect shared data from being concurrently accessed. If a mutex object is destroyed while a thread is blocked waiting for the lock, critical sections and shared data are no longer protected. The behavior of a program is undefined if it destroys a mutex object owned by any thread or a thread terminates while owning a mutex object.
Vulnerability and risk
Destroying a mutex while it is locked may result in invalid control flow and data corruption.
External guidance
Mitigation and prevention
Do not destroy the mutex when it is locked.
Example
Copy
#include <mutex>
#include <thread>
const size_t maxThreads = 10;
std::mutex m2;
using namespace std;
void do_work(size_t i, std::mutex *pm) {
std::lock_guard<std::mutex> lk(*pm);
//printf("hello");
// Access data protected by the lock.
}
void start_threads1() {
std::thread threads[maxThreads];
std::mutex m1;
for (size_t i = 0; i < maxThreads; ++i) {
threads[i] = std::thread(do_work, i, &m1); // Uncompliant code. If you use mutex 'm1' to start
} // several threads, when one thread ends, this mutex
} // will be destroyed while other threads
// are still locking this mutex.
void start_threads2() {
std::thread threads[maxThreads];
for (size_t i = 0; i < maxThreads; ++i) {
threads[i] = std::thread(do_work, i, &m2); //compliant code, by using global mutex variable.
}
}
void run_threads() {
std::thread threads[maxThreads];
std::mutex m3;
for (size_t i = 0; i < maxThreads; ++i) {
threads[i] = std::thread(do_work, i, &m3);
}
for (size_t i = 0; i < maxThreads; ++i) {
threads[i].join(); // compliant code, by using join method.
}
}