? 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 + + * 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 * 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; }