If I attach a file to an existing completion port, do I have to close the completion port handle a second time?

Raymond Chen

There are two ways of calling the Create­IO­Completion­Port function. You can pass a null pointer as the Existing­Completion­Port parameter, indicating that you would like to create a brand new completion port, associated with the file handle you passed (if you passed one). Or you can pass the handle of an existing completion port, and the file handle you passed will be associated with that port, in addition to whatever other file handles are already associated with that port.

In both cases, the return value on success is a handle to the I/O completion port, either the brand new one or the existing one. The question from a customer was, “In the case where I am associating a file handle to an existing completion port, do I need to close the completion port handle a second time?” In other words, is there a handle leak in this code:

BOOL CCompletionPort::Attach(HANDLE h, ULONG_PTR key)
{
 // you are required to have created the completion port first
 assert(m_hPort != nullptr);
 HANDLE hPort = CreateIoCompletionPort(h, m_hPort, key, 0);
 // line missing? if (hPort != nullptr) CloseHandle(hPort);
 return hPort != nullptr;
}

No, there is no handle leak. If you ask to associate a file with an existing completion port, the same handle you passed as the Existing­Completion­Port parameter is returned back on success. There is no new obligation to close the handle a second time because kernel handles are not reference-counted. Closing a kernel handle twice is always an error, because the first close closes the handle, and the second close attempts to use a handle that is already closed. There is no reference count on handles.¹

¹ There is a reference count on kernel objects, but handles are not reference-counted. The standard way to increment the reference count on a kernel object is… to create a new handle to it!

0 comments

Discussion is closed.

Feedback usabilla icon