What happens to a named object when all handles to it are closed?
A customer had a question about named kernel objects:
I understand that handles in a process if leaked will be destroyed by the kernel when the process exits. My question would be around named objects.
Would named objects hold their value indefinitely? If I run a small utility app to increment a named counting semaphore, the count of that named semaphore could be lost when that app exits?
I would expect it to always hold its current value so that transactions across processes and across time could be held even if no process is holding on to it.
When the last handle to a named kernel object (such as a named semaphore or a named shared memory block) is closed, the object itself is destroyed. Doesn’t matter whether you explicitly closed the handle by calling
CloseHandle or the kernel closed the handle for you when it cleaned up the mess you left behind. The object manager doesn’t say, “Well, if the application explicitly called
CloseHandle, then I’ll also delete the named object, but if the application leaked the handle, then I’ll leave the named object around.”
First of all, that would kind of belie the whole concept of clean-up. Cleaning up means destroying the resources the application neglected to.
Second, this would create a bizarre situation where the way to access a new feature is to intentionally do something wrong. (Namely, to leak a handle to a named object.)
Okay, so maybe the expectation was that named objects persisted after all handles to them are closed, even if the handle is closed via the normal
CloseHandle mechanism. But then how would you delete a named object? There is no
DeleteNamedEvent function, after all. You could write a process that created 2 billion named objects and then leaked them. Boom, now you can’t clean up by killing the process; you have to restart the computer.
Kernel objects all follow the same lifetime rules, whether they are named or anonymous: The object is destroyed when the last reference to it is removed (when the handle is closed, noting also that running threads and processes keep a reference to the corresponding kernel object).
If you want something that survives after all its handles are closed, then use something with a persistence model, like a file.