Fix tcflush hang with streaming devices

Brian Ford ford@vss.fsi.com
Wed Dec 10 20:57:00 GMT 2003


This trivial clean up patch fixes the problem reported here:

http://www.cygwin.com/ml/cygwin/2003-10/msg00797.html

Tested and confirmed by the reporter on 98 and 2000sp2.

I tried to find some reason for the previous implimentation via cvs log
and the developers archives, but it seems to have been this way forever.
If anyone knows why this is bad, please speak up.

The reporter is still experiencing "random hangs" in write, but has not
supplied sufficient information for me to track it down.  This problem
existed before and after the patch, so it is unrelated.  I will try to fix
it too if the reporter supplies more info.

2003-12-10  Brian Ford  <ford@vss.fsi.com>

	* fhandler_serial.cc (fhandler_serial::tcflush): Simplify.  Remove
	read polling loop to avoid a hang with streaming devices.

-- 
Brian Ford
Senior Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
Phone: 314-551-8460
Fax:   314-551-8444
-------------- next part --------------
Index: fhandler_serial.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_serial.cc,v
retrieving revision 1.46
diff -u -p -r1.46 fhandler_serial.cc
--- fhandler_serial.cc	7 Dec 2003 22:37:11 -0000	1.46
+++ fhandler_serial.cc	10 Dec 2003 20:13:08 -0000
@@ -497,21 +497,30 @@ fhandler_serial::ioctl (unsigned int cmd
 int
 fhandler_serial::tcflush (int queue)
 {
-  if (queue == TCOFLUSH || queue == TCIOFLUSH)
-    PurgeComm (get_handle (), PURGE_TXABORT | PURGE_TXCLEAR);
+  DWORD flags;
 
-  if (queue == TCIFLUSH || queue == TCIOFLUSH)
-    /* Input flushing by polling until nothing turns up
-       (we stop after 1000 chars anyway) */
-    for (int max = 1000; max > 0; max--)
-      {
-	COMSTAT st;
-	if (!PurgeComm (get_handle (), PURGE_RXABORT | PURGE_RXCLEAR))
-	  break;
-	low_priority_sleep (100);
-	if (!ClearCommError (get_handle (), &ev, &st) || !st.cbInQue)
-	  break;
-      }
+  switch (queue)
+    {
+    case TCOFLUSH:
+      flags = PURGE_TXABORT | PURGE_TXCLEAR;
+      break;
+    case TCIFLUSH:
+      flags = PURGE_RXABORT | PURGE_RXCLEAR;
+      break;
+    case TCIOFLUSH:
+      flags = PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR;
+      break;
+    default:
+      termios_printf ("Invalid tcflush queue %d", queue);
+      set_errno (EINVAL);
+      return -1;
+    }
+	
+  if (!PurgeComm (get_handle (), flags))
+    {
+      __seterrno ();
+      return -1;
+    }
 
   return 0;
 }


More information about the Cygwin-patches mailing list