RFC, fix for bogus timeouts in select()

Øyvind Harboe oyvind.harboe@zylin.com
Thu Oct 21 12:37:00 GMT 2004


-- 
Øyvind Harboe
http://www.zylin.com

-------------- next part --------------
? bogustimeout.txt
Index: current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/fileio/current/ChangeLog,v
retrieving revision 1.46
diff -u -w -r1.46 ChangeLog
--- current/ChangeLog	4 Oct 2004 11:50:06 -0000	1.46
+++ current/ChangeLog	21 Oct 2004 12:32:21 -0000
@@ -1,3 +1,15 @@
+2004-10-21  Oyvind Harboe  <oyvind.harboe@zylin.com>
+
+        * src/select.cxx: Fix problem with bogus timeouts in select().
+	The problem is that a thread can receive data while it is currently
+	starved for CPU. It can then wake up with data arrived and timeout
+	expired. The fix is to check for data after timeout has expired. One
+	can of course claim that select() is "doing the right thing", but
+	it is a royal pain for developers to track down this sort of thing
+	so removing this API tripwire seems worthwhile. E.g. serial drivers
+	can spend a lot of time in DSRs copying lots of traffic. Not easily
+	dealt with at an application level.
+	
 2004-10-01  Oyvind Harboe  <oyvind.harboe@zylin.com>
 
         * src/select.cxx: place the CYGBLD_ATTRIB_INIT_PRI such that it
Index: current/src/select.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/fileio/current/src/select.cxx,v
retrieving revision 1.13
diff -u -w -r1.13 select.cxx
--- current/src/select.cxx	4 Oct 2004 11:50:07 -0000	1.13
+++ current/src/select.cxx	21 Oct 2004 12:32:21 -0000
@@ -224,6 +224,7 @@
         
         CYG_FILEIO_SIGMASK_SET( mask, &oldmask );
     
+		int done=0;    
         do
         {
 
@@ -246,6 +247,13 @@
             if( wake_count == selwake_count )
             {
                 // Nothing found, see if we want to wait
+				if (done)
+				{
+					// nope, we've timed out.
+                    error = EAGAIN;
+					break;
+				}
+
                 if (tv)
                 {
                     // Special case of "poll"
@@ -265,8 +273,10 @@
 
                         if( Cyg_Clock::real_time_clock->current_value() >= ticks )
                         {
-                            error = EAGAIN;
-                            break;
+                        	// we may have been starved for CPU until now, and thus
+                        	// we need to do one more iteration to pick up anything 
+                        	// that is ready for us.
+                            done=1;
                         }
                         else error = EINTR;
                     }


More information about the Ecos-patches mailing list