views:

515

answers:

2

The Microsoft documentation is silent about what happens if I mistakenly call ReleaseMutex() when the mutex is already unlocked.

Details:

I'm trying to fix up some Windows code without having access to the compiler.

I realise that WinApi mutexes are all recursive, and reference-counted. If I were making use of that feature, it's obvious that the extra ReleaseMutex() call would prematurely decrement the reference counter.

However, the code that I am looking at does not use the mutex recursively, so the reference count never gets higher than '1'. It does release the mutex more times than necessary... so what happens? Does the reference count go negative? Does it stay at zero (unlocked) and just return an ignorable error?

(Naturally, this code doesn't actually check for errors when it calls these functions!)

+4  A: 

peejay provided a good link in his comment to the ReleaseMutex documentation. I believe that this line from the documentation answers your question:

The ReleaseMutex function fails if the calling thread does not own the mutex object.

While it is not explicitly said, I think that releasing a mutex (the first time) causes the calling thread to no longer own the mutex object. Thus the second call will simply fail. Such an implementation would make sense too since it would allow easily detecting this type of error (Just check the return value).

Evan Teran
OK, so what error is returned?
alex tingle
"If the function fails, the return value is zero."
Bill
Thank you, Bill for stating the obvious. Here's the full quote: "If the function fails, the return value is zero. To get extended error information, call GetLastError." So, having called GetLastError(), how can I distinguish this error condition from other errors that may occur?
alex tingle
@alex: `GetLastError()` will return a different value for the different error conditions... You can even use `FormatMessage` to create a human readable message from the error code.
Evan Teran
A: 

The rules for a mutex are as follows:

  1. If the thread ID is 0 (an invalid thread ID), the mutex is not owned by any thread and is signaled.
  2. If the thread ID is nonzero, a thread owns the mutex and the mutex is nonsignaled.
  3. Unlike all the other kernel objects, mutexes have special code in the operating system that allows them to violate the normal rules. (I'll explain this exception shortly.)
Davit Siradeghyan
This doesn't really answer the question, does it?
alex tingle