18.3.3 Do not use std::recursive_mutex

Use of std::recursive_mutex is indicative of bad design: Some functionality is expecting the state to be consistent which may not be a correct assumption since the mutex protecting a resource is already locked.

// @@- Non-Compliant: Using recursive_mutex -@@
#include <mutex>
#include <cstdint>
               
class DataWrapper
{
public:
int32_t incrementAndReturnData()
{
std::lock_guard<std::recursive_mutex> guard(mut);
incrementData();
return data;
}
                 
void incrementData()
{
std::lock_guard<std::recursive_mutex> guard(mut);
++data;
}
                 
// ...
private:
mutable std::recursive_mutex mut;
int32_t data;
};

Such situations should be solved by redesigning the code.

// @@+ Compliant: Not using mutex +@@
#include <mutex>
#include <cstdint>
               
class DataWrapper
{
public:
int32_t incrementAndReturnData()
{
std::lock_guard<std::mutex> guard(mut);
inc();
return data;
}
                 
void incrementData()
{
std::lock_guard<std::mutex> guard(mut);
inc();
}
                 
// ...
private:
void inc()
{
// expects that the mutex has already been locked
++data;
}
               
mutable std::mutex mut;
int32_t data;
};

References

  • Williams Concurrency – 3.3.3

Click here for references