Recursive mutex on Windows?

2.9k views Asked by At

As far as I understand, on Windows CRITICAL_SECTION can be used only as a non-recursive mutex. To get recursive mutex you have to use OpenMutex and friends.

However, AFAIU, Win32 Mutex cannot be used with condition variable (InitializeConditionVariable et al.)

Is there a way to use recursive mutex in conjunction with condition variable on Windows?

2

There are 2 answers

0
Martin Sustrik On BEST ANSWER

valdo's comment is right. CRITICAL_SECTION is recursive. Here's a quotation from MSDN: "After a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution." Problem solved.

7
David Schwartz On

That just wouldn't make any sense. Semantically, the point of a condition variable is that you atomically release the lock when you wait -- thus allowing other threads to acquire the lock to do the thing you are waiting for. However, the "release" operation on a recursive mutex may not actually unlock it, so waiting after a release could deadlock. The fact that you want a way to do this strongly suggests something is wrong with your design or your understanding of condition variables.

Think about it -- what should happen when a function that holds a lock on the recursive mutex calls a function that acquires a second lock and then calls the sleep function? If the lock is released, the first function's logic will break since the object will be modified while it held a lock on it. If the lock is not released, the wait will deadlock since the thing it is waiting for can never happen because it holds the lock another thread would need to make it happen.

There is no sensible way to use a condition variable without knowing whether or not you have a lock on it already. And if you know whether or not you have a lock, there's no need for a recursive lock function. If you know you already have a lock, don't bother calling the lock function. If you know you don't already have a lock, the lock function will work fine even if it's not recursive.