The reentrancy problem
A plain mutex deadlocks if the owner tries to lock it again. That happens easily when one locked function calls another locked function in the same module.
How recursion is allowed
A recursive mutex tracks two extra things beyond the locked flag.
- The owner identity, so it can tell if the current thread already holds it.
- A count of how many times the owner has locked it.
When the owning thread locks again, the mutex just increments the count instead of blocking. Each unlock decrements the count, and the lock is only released to others when the count reaches zero.
The cost
Recursive locks hide design problems. A thread can lock the same data several layers deep without noticing, which makes reasoning about invariants harder. Many guides prefer restructuring code so a plain mutex suffices.
Key idea
A recursive mutex stores the owner and a count so the same thread can relock safely; it trades convenience for weaker guarantees about how deeply you hold a lock.