Concurrency Part 6 – Abandoned mutex

This is the sixth part of the Concurrency series. For your convenience you can find other parts in the table of contents in Part 1 – Mutex performance in .NET

Let’s start with the following code:

We want to acquire a mutex. Since the operation might fail, we want to log the timeout, handle the exception and try again. Finally, we want to release the mutex, catch all exceptions and then exit.

Start this application three times: first instance should acquire the mutex, second and third should just wait. Now kill forcibly first instance (i.e., using Process Explorer). Now one of two other instances should acquire the mutex. Let’s say, that it was the second instance. Focus it and hit enter. It should say Mutex released and wait on another Console.ReadLine(). We expect the third instance to acquire the mutex, however, it still shows timeouts. Why is that?

Explanation

You could use Chain Traversal API to figure out what is happening. However, everything is as designed. If you consult the documentation, you will see the following exception:

What is not stated explicitly is: when you get this exception, the mutex IS acquired. This means that our first catch just swallows the exception of an operation which actually succeeded. We loop again, acquire the mutex again (since it is recursive). Later when we release it, it is still locked because we miss one more release.

Solution? Whenever you get this exception you need to break the loop because the mutex is acquired.