[2/3] Stop flooding with EV_RXCHAR

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Sun May 11 18:22:14 CDT 2008


Generate an EV_RXCHAR event only if a new character arrived
instead of everytime WaitCommEvent is called while the queue
is non-empty. There is software where one thread polls the
queue and sends a message to another thread to read from
the queue as soon as EV_RXCHAR occurred, so WaitCommEvent
is reentered before the buffer has been read.

The new EV_RXCHAR generation code has to handle a Linux quirk
that TIOCGICOUNT might report characters that TIOCINQ does not
yet report, as windows software does not expect that if after
an EV_RXCHAR event the queue has been emptied (by reading
AmountInInQueue characters) characters could arrive without
another EV_RXCHAR event.
---

supercedes the "Stop flooding with EV_TXEMPTY and EV_RXCHAR"
patch.

 dlls/ntdll/serial.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c
index 7aeb01c..109804b 100644
--- a/dlls/ntdll/serial.c
+++ b/dlls/ntdll/serial.c
@@ -893,7 +893,7 @@ static NTSTATUS get_irq_info(int fd, serial_irq_info *irq_info)
 

 static DWORD WINAPI check_events(int fd, DWORD mask, 
-                                 const serial_irq_info *new, 
+                                 serial_irq_info *new, 
                                  const serial_irq_info *old,
                                  DWORD new_mstat, DWORD old_mstat)
 {
@@ -914,15 +914,22 @@ static DWORD WINAPI check_events(int fd, DWORD mask,
     if ((old_mstat & MS_RING_ON) != (new_mstat & MS_RING_ON)) ret |= EV_RING;
     if ((old_mstat & MS_RLSD_ON) != (new_mstat & MS_RLSD_ON)) ret |= EV_RLSD;
     if (old->frame != new->frame || old->overrun != new->overrun || old->parity != new->parity) ret |= EV_ERR;
-    if (mask & EV_RXCHAR)
+    if (old->rx != new->rx && mask & EV_RXCHAR)
     {
-	queue = 0;
+	queue = 1; /* if queue can't be queried, assume something in it */
 #ifdef TIOCINQ
 	if (ioctl(fd, TIOCINQ, &queue))
 	    WARN("TIOCINQ returned error\n");
 #endif
 	if (queue)
 	    ret |= EV_RXCHAR;
+        else
+        {
+            /* Maybe, the read characters did not reach the queue yet.
+               This *does* happen on Linux! */
+            TRACE("Delaying RX_CHAR event due to empty input queue\n");
+            new->rx = old->rx;
+        }
     }
     if (mask & EV_TXEMPTY)
     {
-- 
1.5.5.1




More information about the wine-patches mailing list