3
votes

In my project I need to read from and write to a serial port (RS232). I am using overlapped IO and use two separate threads for reading and writing.

When I issue a write operation that does not complete immediately, I start waiting (WaitForMultipleObjects) on two events; the event assigned to the hEvent member of the overlapped structure, and a stop event. When I want to stop the thread, I signal the stop event by calling SetEvent(). This causes the wait function to return. Because the write operation is still pending I cancel the operation by calling CancelIO(). Then again, I wait for the operation to complete, now using GetOverlappedResult() with the bWait parameter set to True. When the operation completes, GetOverlappedResult() returns False and GetLastError() returns ERROR_OPERATION_ABORTED.

Now here's my question:

When GetOverlappedResult() returns False, and GetLastError() returns ERROR_OPERATION_ABORTED (indicating a completed, but canceled operation), is the lpNumberOfBytesTransfered parameter valid? In other words, does the lpNumberOfBytesTransfered give me the actual number of written bytes before it was canceled? Or is the lpNumberOfBytesTransfered parameter undefined in this case?

1
Since you are already embracing threads, why are you choosing to use async I/O? Asynch I/O is way more complex than blocking I/O, and since you are happy to move code into threads, surely it's easier to use blocking I/O? Or am I missing some reason why you chose aysnc?David Heffernan
By using overlapped i/o in seperate threads, i am able to issue ReadFile operations and WaitCommEvent operations in one thread, and WriteFile operations in the other. And because they are overlapped, I can let the thread wait on the operations to complete, and on a stop event, allowing me to cancel the oeprations. Blocking i/o is much harder to cancel.R. Beiboer
This is a driver implementation detail. There are many possible serial port drivers around, they often get emulated by a USB or BlueTooth device driver. Often of questionable quality. The standard Microsoft driver already says no, it forces the IRP.IOStatus.Information field to 0 when the IRP gets cancelled. Don't cancel I/O if you cannot afford data loss.Hans Passant
Thank you @HansPassant . I'd like to accept your comment as an answer, but that's not possible with comments.R. Beiboer
I already posted an answer but it got quickly downvoted. No idea why, hard to learn something new when downvoters don't share their knowledge. Afaik, my comment is accurate. Feel free to just copy it in your own post and mark that as the answer.Hans Passant

1 Answers

3
votes

I will repeat Hans Passant's comment, because I think he gives an accurate answer to my question:

This is a driver implementation detail. There are many possible serial port drivers around, they often get emulated by a USB or BlueTooth device driver. Often of questionable quality. The standard Microsoft driver already says no, it forces the IRP.IOStatus.Information field to 0 when the IRP gets cancelled. Don't cancel I/O if you cannot afford data loss.