http://bugs.winehq.org/show_bug.cgi?id=19713
--- Comment #4 from Juan Lang juan_lang@yahoo.com 2009-08-12 18:07:05 --- Are you sure this isn't a race condition? You create the event as an auto-reset event, that is, with bManualReset = FALSE: ovOverlapped.hEvent = CreateEvent(NULL, FALSE/*TRUE*/, FALSE, NULL);
From MSDN's remarks section on GetOverlappedResult:
Specify a manual-reset event object in the OVERLAPPED structure. If an auto-reset event object is used, the event handle must not be specified in any other wait operation in the interval between starting the overlapped operation and the call to GetOverlappedResult. For example, the event object is sometimes specified in one of the wait functions to wait for the operation's completion. When the wait function returns, the system sets an auto-reset event's state to nonsignaled, and a subsequent call to GetOverlappedResult with the bWait parameter set to TRUE causes the function to be blocked indefinitely.
And this is what you do: you call WaitForSingleEvent on the event until it's signalled, then call GetOverlappedResult on it: while (dwResult = WaitForSingleObject(ovOverlapped.hEvent, 50) == WAIT_TIMEOUT) (snip) if (!(bOvResult = GetOverlappedResult(hSerial, &ovOverlapped, &dwOvRes, TRUE)))
I'm curious why you commented out /*TRUE*/ when you created the event. Based on MSDN's comments, I think some more testing on more than one Windows version and with more than one serial driver would be in order before concluding that Windows *always* behaves this way.