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!)
The number of calls is kept by the common language runtime. The thread must call ReleaseMutex the same number of times to release ownership of the mutex. If a thread terminates while owning a mutex, the mutex is said to be abandoned. The state of the mutex is set to signaled and the next waiting thread gets ownership.
ReleaseMutex () will then fail with an ERROR_INVALID_HANDLE error code if called with the closed mutex handle. If the mutex is named, there is a single reference-counted kernel object backing the mutex, but CreateMutex () and OpenMutex () return unique HANDLE values that have to be closed individually.
If I call CloseHandle on a mutex before a thread has finished with the mutex, and hence, hasn't yet called ReleaseMutex, what is the expected behaviour? CloseHandle () immediately destroys the handle that is passed to it. ReleaseMutex () will then fail with an ERROR_INVALID_HANDLE error code if called with the closed mutex handle.
But, the mutex will still be owned by that thread with no way to release it, affecting other threads waiting for mutex lock. Thanks for contributing an answer to Stack Overflow!
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With