So, I'm trying to use overlapped IO for file and network operations using IOCP. I noticed that at least some, if not all overlapped functions support the notion of a completion routine which receives both an error code as well the number of bytes transferred, if applicable. Unfortunately, I cannot use that because while my threading model does serialize I/O operations when necessary (e.g. streams), it does not guarantee that they will come from the same thread for any given Handle.
In this sense, a naive implementation would have to use GetOverlappedResult to check for errors after every IOCP dequeue operation, which involves non-negligible overhead, especially when the number of bytes transferred is small.
Alternatively, I could condition the above call on the return value of GetQueuedCompletionStatus which states that:
Upon failure (the return value is FALSE), (...) if *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port, the function stores information about the failed operation in the variables pointed to by lpNumberOfBytes, lpCompletionKey, and lpOverlapped. To get extended error information, call GetLastError.
Are there any similar provisions available for GetQueuedCompletionStatusEx? In other words, is there any way to recover the return value of an equivalent GetQueuedCompletionStatus using only the information provided by its OVERLAPPED_ENTRY? Please keep in mind that I am looking for a generic solution that covers not just data transfers, but all of the functions that can be monitored via IOCP (e.g. AcceptEx, locks, folder monitoring, etc.)
Thanks!