...
- Every mutex has two members, _WaitEvHandle, which is a automatic reset Win32 event handle used for blocking, and _ThreadId, the ID of the current thread
- _ThreadId is initialized to 0
- To lock,
mtx_lock
calls InterlockedCompareExchange on _ThreadId. If the return value is 0, we successfully locked the mutex. If it is not 0, then we must block, so go ahead and block on the event handle - To unlock,
mtx_unlock
sets _ThreadId to 0 and invokes SetEvent to unblock a thread - Note that at no point once someone has blocked on the mutex will the _State member return to -1 until all threads blocked on the mutex
Waits with timeouts
Timed waits must be careful about lowering the _State variable after their wait times out. In particular, if after the timeout _State == 0, then they actually just got granted the mutex - and, more importantly - the event object is set. When this occurs, they must do a wait with a timeout of zero on the event object and repeat this every time the wait times out until _State no longer equals 0 (which indicates somebody else took the mutex) or until the wait completes (indicating that they got the mutex)