[4/4] ntdll: Properly set flag which indicates buffer empty state.
Wolfgang Walter
wine at stwm.de
Wed Aug 28 07:28:03 CDT 2013
Hello Dimitry,
I think I now found the difference between my patches and yours and what makes
that one application fail (with or without [4/4] ntdll: Properly set flag
which indicates buffer empty state.)
My patch removes the attempt to flag EV_TXEMPTY only once.
In check_events() EV_TXEMPTY is set:
if (mask & EV_TXEMPTY)
{
if (!old->temt && new->temt)
ret |= EV_TXEMPTY;
}
I think that happens:
* application writes data to com port.
* all is written, serial buffer is empty
* application calls WaitCommEvent()
* wait_on() is called
* wait_on() calls get_irq_info()
* get_irq_info() sets commio->irq_info->temt = 1
* wait_on() calls check_events() and uses sets commio->irq_info for old an new
* so old->temt == new->temt and EV_TXEMPTY is not set
* if there are no other events (in real world basically EV_RXCHAR):
* wait_for_event() is startet with commio->irq_info->temt set to one
* wait_for_event() calls get_irq_info() with new_irq_info()
* get_irq_info() sets new_irq_info->temt = 1 because the buffer is still empty
* wait_for_event() calls check_events() with new_irq_info and commio->irq_info
* again check_events() will not set EV_TXEMPTY as both have temt == 1
It seems that we do not recover from that hang.
Please correct me if I misread the code and I'm wrong.
I think it's better if WaitCommEvent() returns with EV_TXEMPTY even if there
has no new data been sent in between:
* if an application waits only for EV_TXEMPTY then there is no problem.
* if it waits for i.e. EV_TXEMPTY|EV_RXEMPTY it may busy loops. Still better
then not waiting forever.
Sending EV_TXEMPTY only once after the write buffer got empty is not easy to
implement I think. One way would be: block a write until it finished and
buffer is empty, the set a flag.
Am Mittwoch, 28. August 2013, 12:41:00 schrieb Dmitry Timoshkov:
> Dmitry Timoshkov <dmitry at baikal.ru> wrote:
> > Alexandre Julliard <julliard at winehq.org> wrote:
> > > It doesn't work here:
> > >
> > > ../../../tools/runtest -q -P wine -M kernel32.dll -T ../../.. -p
> > > kernel32_test.exe.so comm.c && touch comm.ok comm.c:835: Test failed:
> > > WriteFile took 1 ms to write 17 Bytes at 150 Baud comm.c:848: Test
> > > failed: WaitCommEvent failed with a timeout
> > > comm.c:859: Test failed: WaitCommEvent error 997
> > > comm.c:860: Test failed: WaitCommEvent: expected EV_TXEMPTY, got 0
> > > comm.c:865: Test failed: WaitCommEvent used 1000 ms for waiting
> > > comm.c:1895: Tests skipped: interactive tests (set
> > > WINETEST_INTERACTIVE=1)
> > > make: *** [comm.ok] Error 5
> >
> > I assume it's a real hardware and not a VM? Is this with a real COM port,
> > or USB-serial cable? If the latter one what driver is it using?
>
> Looking at the failure messages above once again, I can say that WriteFile
> failure is definitely not caused by this patch. Does running the test
> several times cause the same failures? In any case it would be interesting
> to see the +comm log with "ntdll: Add a trace for transmitter's buffer
> empty flag." applied.
>
> And current logic of setting the empty buffer flag is really broken, it
> always sets the flag to a not zero value if ioctl(TIOCOUTQ) succeeds.
Regards,
--
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts
Abteilungsleiter IT
Leopoldstraße 15
80802 München
More information about the wine-devel
mailing list