I have thread-safe Document class representing custom document.
It have getters (const functions) and setters to modify it's state.
All these functions are mutex-protected to guarantee document will not changed
until the method will be completely executed.
But due to QMutex usage, i can't mark state-accessed function
as const without mutable usage. Capturing QMutex change it's state.
Is this code correct, or it can be written in a more nice way?
Without hacky mutable usage.
class Document
{
// This method should be const: it changes only mutex
// and don't touch document state
bool IsCorrect() const;
...
mutable QMutex m_lock;
};
bool Document::IsCorrect() const
{
// Capturing mutex object change it!
QMutexLocker lock( &m_lock );
... Const-aware code
bool result = ( m_context != NULL );
...
return result;
}
The standard library mutex allocates, so it cannot be a const fn without changing its implemenation. The one in parking_lot can be used instead.
Mutexes are used to protect shared data structures being concurrently accessed. If a mutex is destroyed while a thread is blocked waiting for that mutex, critical sections and shared data are no longer protected. The mtx_destroy function releases any resources used by the mutex pointed to by mtx .
To solve your issue, you can use std::recursive_mutex , which can be locked/unlocked multiple times from the same thread. From cppreference: A calling thread owns a recursive_mutex for a period of time that starts when it successfully calls either lock or try_lock .
Mutex and mutable go together (M&M rule, C++11)If a member variable is itself a mutex, it should be mutable. This is required to use it inside a const member function.
Herb Sutter has an excellent talk on Channel9 about this topic.
The point relevant here is that in C++11, mutable has gained a new meaning regarding thread safety: "this data member is internally synchronised." That's precisely what a mutex is. Herb even says in that talk when talking about a mutex: "it wants to be mutable."
So having a mutable mutex and accessing it from a const member function is not hacky at all, and it's in fact one of the primary intended uses for mutable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With