According the this, unique_lock
can be used for recursive locking by declaring a std::unique_lock<std::recursive_mutex>
, and in fact that compiles fine.
However, it appears from examining the code (gcc 4.8.2 and 4.9.0) that unique_lock
doesn't defer to _Mutex.lock
, but rather implements the lock method itself:
void
lock()
{
if (!_M_device)
__throw_system_error(int(errc::operation_not_permitted));
else if (_M_owns)
__throw_system_error(int(errc::resource_deadlock_would_occur));
else
{
_M_device->lock();
_M_owns = true;
}
Clearly, this prevents recursive locking of the mutex, and in fact attempting to recursively lock throws the resource_deadlock_would_occur
exception.
Am I missing something here, is this a bug, or is the documentation for unique_lock just wrong?
TIA!!!
A common mistake is to confuse the
mutex
with thelock
. Amutex
is an object that can be shared among threads (otherwise it would be useless). A lock however is not itself a thread-safe object. It should not be shared among threads. It is typically a local object on a stack. For example:In the example above, if
foo()
is called recursively, you have undefined behavior because you will lockmut
recursively. On each recursion, you get a newunique_lock
though. So theunique_lock
is not aware of the recursion. If you really need to callfoo()
recursively, you need to use a recursive mutex, for example:So: Yes, you can use
std::unique_lock<std::recursive_mutex>
, and yes, your implementation is correct.