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
1 #include <mutex> 2 #include <thread> 3 4 const size_t maxThreads = 10; 5 std::mutex m2; 6 using namespace std; 7 8 void do_work(size_t i, std::mutex *pm) { 9 std::lock_guard<std::mutex> lk(*pm); 10 //printf("hello"); 11 // Access data protected by the lock. 12 } 13 14 void start_threads1() { 15 std::thread threads[maxThreads]; 16 std::mutex m1; 17 18 for (size_t i = 0; i < maxThreads; ++i) { 19 threads[i] = std::thread(do_work, i, &m1); // Uncompliant code. If you use mutex 'm1' to start 20 } // several threads, when one thread ends, this mutex 21 } // will be destroyed while other threads 22 // are still locking this mutex. 23 void start_threads2() { 24 std::thread threads[maxThreads]; 25 26 for (size_t i = 0; i < maxThreads; ++i) { 27 threads[i] = std::thread(do_work, i, &m2); //compliant code, by using global mutex variable. 28 } 29 } 30 31 void run_threads() { 32 std::thread threads[maxThreads]; 33 std::mutex m3; 34 35 for (size_t i = 0; i < maxThreads; ++i) { 36 threads[i] = std::thread(do_work, i, &m3); 37 } 38 39 for (size_t i = 0; i < maxThreads; ++i) { 40 threads[i].join(); // compliant code, by using join method. 41 } 42 }