- Process PA creates and owns named mutex M.
- Process PB "creates" a mutex by the same name. (GetLastError returns ERROR_ALREADY_EXISTS, so PB knows it didn't really create M, but that's beyond the scope of this discussion.)
- PA has done whatever it needed to, decides it is done with M, and closes its handle to M. M still exists, of course, because PB still has a handle to it. But M has just entered a "limbo" state in which it's useless to everyone and everything.
- PB attempts to "own" the mutex by passing it to WaitForSingleObject, and let's suppose for the sake of discussion that PB passes an INFINITE time-out to WaitForSingleObject.
Here's an alternate sequence of events:
- Process PA creates and owns named mutex M.
- Process PB "creates" a mutex by the same name. (GetLastError returns ERROR_ALREADY_EXISTS, so PB knows it didn't really create M, but that's beyond the scope of this discussion.)
- PB attempts to "own" the mutex by passing it to WaitForSingleObject, and let's suppose for the sake of discussion that PB passes an INFINITE time-out to WaitForSingleObject.
- PA has done whatever it needed to, decides it is done with M, and closes its handle to M. M still exists, of course, because PB still has a handle to it. But M has just entered a "limbo" state in which it's useless to everyone and everything.
In both sequences, PB is now stuck; WaitForSingleObject will never return. The only difference is that I expected PB to block in the second sequence after step 3 but then unblock after step 4. It's possible PA could "create" another handle to the mutex and pass the handle to ReleaseMutex, and I didn't try that, but it would be consistent with the notion that CloseHandle closes a handle to the mutex object, which exists in the kernel independently of the handle. Still, PA "creating" the handle again would be weird, and I expected CloseHandle to have the same effect as PA exiting, which was wrong.
1 comment:
Good post, I came across the similar situation. Basically CloseHandle() destroys the handle but it doesn't release the mutext, you have to call ReleaseMutex() to do that.
Post a Comment