Dmitry Timoshkov <dmi...@baikal.ru> wrote: > Wolfgang Walter <w...@stwm.de> wrote: > > > 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: > > That means that WaitCommEvent(EV_TXEMPTY) without any prior WriteFile > would always return success and signal the EV_TXEMPTY event. My tests > show that WaitCommEvent(EV_TXEMPTY) fails with a timeout in this case. > Since the serial device is very slow it should be unlikely that after > successful WriteFile() with some data WaitCommEvent() sees an already > empty transmitter's output queue.
One of the solutions to this would be that WriteFile sets a flag for a being written handle indicating that there were data pending for this handle, then WaitCommEvent(EV_TXEMPTY) in the case of empty output queue would see that flag, clear it and set EV_TXEMPTY flag in the events mask. That would also explain why SetCommMask() called after WriteFile() makes WaitCommEvent(EV_TXEMPTY) fail with a timeout in some testbot VMs, in that case SetCommMask() would also clear the data pending write flag. -- Dmitry.