I am using QSerialPort to write to a USB serial device on Windows 7, and I was getting the error signal with the QSerialPort::UnknownError error code after doing a write. GetLastError in my error slot was returning ERROR_IO_INCOMPLETE. I believe this is because a QTimer with zero timeout is used on Windows to check the result of the async write operation rather than getting notified by Windows when the operation is actually complete. A side effect of this is that the same data was getting written twice for a single call to write because _q_completeAsyncWrite was setting writeStarted to false when GetOverlappedResult returned FALSE.
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683209(v=vs.85).aspx for documentation of GetOverlappedResult. It says if the operation is still pending and bWait is FALSE, GetOverlappedResult will return FALSE and GetLastError will be ERROR_IO_COMPLETE.
If I add the following lines right after the call to GetOverlappedResult in _q_completeAsyncWrite, the problem seems to be fixed.
But I'm not sure if this is the proper fix – does this just keep triggering a QTimer to go off until the I/O operation is really complete, or could there be a long delay before it checks the result again (i.e. how is a call to _q_completeAsyncWrite re-triggered if it just returns as above)?
In addition, _q_completeAsyncRead and _q_completeAsyncCommunication both call GetOverlappedResult and do not check for ERROR_IO_INCOMPLETE, so they may need a similar treatment.
Here is the my complete modified _q_completeAsyncWrite for context: