http://bugs.winehq.org/show_bug.cgi?id=9988
--- Comment #3 from Tom Brus tombrus@gmail.com 2007-10-21 14:00:10 --- I got the sources of the windows application and have determined what is going wrong. Unfortunately I can not share the sources themselves for copyright reasons.
I pinpointed the problem to the WaitCommEvent() function (which does the IOCTL_SERIAL_WAIT_ON_MASK). I deduced that under windows this function will probably never return true. It always returns false with the GetLastError() being ERROR_IO_PENDING. This is at least seems to be true for the situation where the rcv and tx buffers are both empty and SetCommMask() is set to (EV_RXCHAR | EV_TXEMPTY).
In contrast the wine implementation returns true (because of the 'shortcut' discussed previously in this bug).
The following abbreviated code is based on the windows application code. I stripped some unimportant details:
for (;;) { ok = WaitCommEvent(...); if (ok) { if (chars_available_for_read==0) continue; } else { switch (GetLastError()) { case ERROR_IO_PENDING: break; default : report_error();break; } } switch (WaitForMultipleObjects(...)) { ... } }
This code runs fine on windows and hangs under wine. I traced it under wine and the following happens: WaitCommEvent() returns true because the tx buffer is empty; the chars_available_for_read is 0 so the for loop will start over. This will happen in an endless succession: a classic hang.
You can argue in several ways that this code can be improved but that is beside the point: it works under windows. You can also argue that wine's WaitCommEvent() works according to the manual, but that is again besides the point because wine should emulate windows, not its manual, right? ;)
On second evaluation the above fix and patch are correct. Could whoever is responsible please look at them and either discuss options or apply the patch. Thanks.