CloseHandle and pending I/O operations

I am trying to understand what happens if application calls CloseHandle and there are pending I/O operations on this handle.

First of all is it a valid scenario? Should I make sure that all I/O on the file handle have been completed before calling CloseHandle? Does it depend on whether the handle was marked as overlapped?

Does system track I/O operation on per-handle or per-file object basis? I mean if there are two handles (original + DuplicateHandle) to a file object and application calls CloseHandle on one of them will this cancel I/O operations that was started via this handle or system will wait until all handles for the file object are closed?

Does system block CloseHandle until all pending I/O operations are completed (assuming this is the last handle to the file object)? Or it just marks pending requests for cancellation and returns (with what error code?). Does it depend on whether the handle was marked as overlapped? If CloseHanle returns without blocking should I consider the handle invalidated or I need to call CloseHandle again until success?

And another question not related to the topic: MSDN says for async I/O: “Do not deallocate or modify the OVERLAPPED structure or the data buffer until all asynchronous I/O operations to the file object have been completed.” (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx) Did they really mean ALL async operations? What if have several asyncs pending and I receive notification that particular operation has been completed. I am still cannot deallocate OVERLAPPED struct for this request because there are other asyncs pending, am I?

Thanks in advance

> I am trying to understand what happens if application calls CloseHandle…

If handle refcount goes down to zero as a result of this call, your driver will receive IRP_MJ_CLEANUP. If total refcount goes down to zero as well your driver will receive IRP_MJ_CLOSE…

… and there are pending I/O operations on this handle.

It is your driver’s responsibility to take care of everything…

First of all is it a valid scenario? Should I make sure that all I/O on the file handle have been
completed before calling CloseHandle? Does it depend on whether the handle was marked
as overlapped?

How can you possibly ensure something like that??? Just consider what happens if your process gets terminated by user - all handles will get closed behind the scenes anyway, so this is just out of your control…

Does system track I/O operation on per-handle or per-file object basis? I mean if there are
two handles (original + DuplicateHandle) to a file object and application calls CloseHandle on one
of them will this cancel I/O operations that was started via this handle or system will wait until all
handles for the file object are closed?

Nothing will happen if handle refcount is non-zero (i.e. only one of the handles gets closed)…

Anton Bassov

> How can you possibly ensure something like that??? Just consider what happens

if your process gets terminated by user - all handles will get closed behind the
scenes anyway, so this is just out of your control…

If process terminates you doesn’t care about input/output buffers and OVERLAPPED structure life cycle, otherwise you does. This quotation from MSDN suggests that just closing handle is troublesome:

"As previously stated, when working with an asynchronous handle, applications should use care when making determinations about when to free resources associated with a specified I/O operation on that handle. If the handle is deallocated prematurely, ReadFile or WriteFile may incorrectly report that the I/O operation is complete. Further, the WriteFile function will sometimes return TRUE with a GetLastError value of ERROR_SUCCESS, even though it is using an asynchronous handle (which can also return FALSE with ERROR_IO_PENDING). "

(http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx)

CloseHandle will only return when all IOs issued for it finish. If it’s a disk (or other DASD) file, then I’m not sure if the filesystem will try to cancel the pending requests; storport’sys doesn’t do cancel anyway.

If it’s a special device handle, it will receive IRP_MN_CLEANUP, and it’s up to the driver to cancel the pending requests.

But CloseHandle is synchronous. Note that its return may not mean every OVERLAPPED will be updated, because that’s done by user mode APCs which are asynchronous.

WRT to the question about deallocating the OVERLAPPED, remember that you
must use a DISTINCT block of memory for each IOOP, so the question is
irrelevant.

The behaviour of CloseHandle is dependent on the handle type (stack) as well
as the driver implementation. it is always synchronous (otherwise handle
reuse would have no reliable implementation), but pending IO may complete or
be cancelled and the UM app has no control over this. Note that the status
returned for each IOOP should indicate what happened to it, so the question
is why do you care? If you are asking if it is best practices to ensure
quiescence before closing a handle, then the answer it ‘it depends on what
kind and your overall design’

wrote in message news:xxxxx@ntdev…

I am trying to understand what happens if application calls CloseHandle and
there are pending I/O operations on this handle.

First of all is it a valid scenario? Should I make sure that all I/O on the
file handle have been completed before calling CloseHandle? Does it depend
on whether the handle was marked as overlapped?

Does system track I/O operation on per-handle or per-file object basis? I
mean if there are two handles (original + DuplicateHandle) to a file object
and application calls CloseHandle on one of them will this cancel I/O
operations that was started via this handle or system will wait until all
handles for the file object are closed?

Does system block CloseHandle until all pending I/O operations are completed
(assuming this is the last handle to the file object)? Or it just marks
pending requests for cancellation and returns (with what error code?). Does
it depend on whether the handle was marked as overlapped? If CloseHanle
returns without blocking should I consider the handle invalidated or I need
to call CloseHandle again until success?

And another question not related to the topic: MSDN says for async I/O: “Do
not deallocate or modify the OVERLAPPED structure or the data buffer until
all asynchronous I/O operations to the file object have been completed.”
(http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx)
Did they really mean ALL async operations? What if have several asyncs
pending and I receive notification that particular operation has been
completed. I am still cannot deallocate OVERLAPPED struct for this request
because there are other asyncs pending, am I?

Thanks in advance