[project @ 2000-04-03 15:24:21 by rrt]
[ghc-hetmet.git] / ghc / rts / Select.c
index b736129..79b21ba 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Select.c,v 1.8 2000/01/17 17:33:30 simonmar Exp $
+ * $Id: Select.c,v 1.12 2000/04/03 15:24:21 rrt Exp $
  *
  * (c) The GHC Team 1995-1999
  *
@@ -52,6 +52,7 @@ awaitEvent(rtsBool wait)
     int numFound;
     nat min, delta;
     int maxfd = -1;
+    rtsBool select_succeeded = rtsTrue;
    
     struct timeval tv;
 #ifndef linux_TARGET_OS
@@ -105,8 +106,18 @@ awaitEvent(rtsBool wait)
 
        case BlockedOnDelay:
          {
-           if (tso->block_info.delay < min)
-             min = tso->block_info.delay;
+           int candidate; /* signed int is intentional */
+#if defined(HAVE_SETITIMER) || defined(mingw32_TARGET_OS)
+           candidate = tso->block_info.delay;
+#else
+           candidate = tso->block_info.target - getourtimeofday();
+           if (candidate < 0) {
+             candidate = 0;
+           }
+#endif
+           if ((nat)candidate < min) {
+             min = candidate;
+           }
            continue;
          }
 
@@ -153,8 +164,10 @@ awaitEvent(rtsBool wait)
         * serviced.
         */
        if (signals_pending()) {
-         start_signal_handlers();
          RELEASE_LOCK(&sched_mutex);
+         start_signal_handlers();
+         /* Don't wake up any other threads that were waiting on I/O */
+         select_succeeded = rtsFalse;
          break;
        }
 
@@ -163,6 +176,7 @@ awaitEvent(rtsBool wait)
         */
        if (run_queue_hd != END_TSO_QUEUE) {
          RELEASE_LOCK(&sched_mutex);
+         select_succeeded = rtsFalse;
          break;
        }
        
@@ -199,22 +213,37 @@ awaitEvent(rtsBool wait)
        next = tso->link;
        switch (tso->why_blocked) {
        case BlockedOnRead:
-         ready = FD_ISSET(tso->block_info.fd, &rfd);
+         ready = select_succeeded && FD_ISSET(tso->block_info.fd, &rfd);
          break;
        
        case BlockedOnWrite:
-         ready = FD_ISSET(tso->block_info.fd, &wfd);
+         ready = select_succeeded && FD_ISSET(tso->block_info.fd, &wfd);
          break;
        
        case BlockedOnDelay:
-         if (tso->block_info.delay > delta) {
-           tso->block_info.delay -= delta;
-           ready = 0;
-         } else {
-           tso->block_info.delay = 0;
-           ready = 1;
+         {
+#if defined(HAVE_SETITIMER) || defined(mingw32_TARGET_OS)
+           if (tso->block_info.delay > delta) {
+             tso->block_info.delay -= delta;
+             ready = 0;
+           } else {
+             tso->block_info.delay = 0;
+             ready = 1;
+           }
+#else
+           int candidate; /* signed int is intentional */
+           candidate = tso->block_info.target - getourtimeofday();
+           if (candidate < 0) {
+             candidate = 0;
+           }
+           if ((nat)candidate > delta) {
+             ready = 0;
+           } else {
+             ready = 1;
+           }
+#endif
+           break;
          }
-         break;
        
        default:
          barf("awaitEvent");