public void OnThreadExiting() { // Abandon locked mutexes. Acquired mutexes are prepended to the linked list, so the mutexes are abandoned in // last-acquired-first-abandoned order. s_lock.Acquire(); try { while (true) { WaitableObject waitableObject = LockedMutexesHead; if (waitableObject == null) { break; } waitableObject.AbandonMutex(); Debug.Assert(LockedMutexesHead != waitableObject); } } finally { s_lock.Release(); } }