exist common behavior for all asynchronous api, it implicit described in CancelThreadpoolIo function
note, by design we need call CancelThreadpoolIo when and only when will not notify to the I/O completion port and the associated I/O callback function will not be called.
you must call the CancelThreadpoolIo
function for either of the
following scenarios:
- An overlapped (asynchronous) I/O operation fails (that is, the asynchronous I/O function call returns failure with an error code
other than ERROR_IO_PENDING
).
- An asynchronous I/O operation returns immediately with success and the file handle associated with the I/O completion object has the
notification mode FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
. The file
handle will not notify the I/O completion port and the associated I/O
callback function will not be called.
so let dwErrorCode
error code returned by api (NOERROR
if win32 api return TRUE)
the next function say you - will be or not notify to IOCP
bool IsWillBeNotification(ULONG dwErrorCode, BOOL bSkipCompletionPortMode)
{
switch (dwErrorCode)
{
case ERROR_IO_PENDING:
return true;
case NOERROR:
return !bSkipCompletionPortMode;
default:
return false;
}
}
in case we use native API and NTSTATUS
bool IsWillBeNotification(NTSTATUS status, BOOL bSkipCompletionPortMode)
{
return (status == STATUS_PENDING) || (!NT_ERROR(status) && !bSkipCompletionPortMode);
}
so:
- if
STATUS_PENDING
- will be IOCP packet
- if
NT_ERROR(status)
- will be no packet (status in range [0xC0000000,
0xFFFFFFFF]
)
- otherwise based on bSkipCompletionPortMode - will be if it not set
note that this is general rule for any asynchronous io api. only NtLockFile
/LockFileEx
- exception from this rule - can be IOCP notification even if api just fail, due to error inside NtLockFile
implementation