Non-recursive mutex
Most mutexes are (or at least should be) non-recursive. A mutex is an object that can be received or released atomically, which allows you to transfer data that is distributed between several streams, which must be protected from race conditions, data distortion and other unpleasant things.
One mutex should ever be received once by one thread in the same call chain. Trying to get (or hold) the same mutex twice within the same thread context should be considered an invalid script and should be handled accordingly (usually through ASSERT, because you are breaking the fundamental contract of your code).
Fractal Mutex
. , , , .
. , , . , , .
, .
, , . , , :
Thread 1
Acquire mutex A
// Modify or read shared data
Release mutex A
Thread 2
Attempt to acquire mutex A
Block as thread 1 has mutex A
When thread 1 has released mutex A, acquire it
// Modify or read shared data
Release mutex A
, , (, A B). , :
Thread 1
Acquire mutex A
// Access some data...
*** Context switch to thread 2 ***
Thread 2
Acquire mutex B
// Access some data
*** Context switch to thread 1 ***
Attempt to acquire mutex B
Wait for thread 2 to release mutex B
*** Context switch to thread 2 ***
Attempt to acquire mutex A
Wait for thread 1 to release mutex A
*** DEADLOCK ***
, , - ABBA.
, , (, A, B).