select() and poll(): change order of events in main timing loop
so that very short selects/polls don't just cause a timeout with
no real test.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@466 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c
index d736558..cca2d88 100644
--- a/coregrind/vg_libpthread.c
+++ b/coregrind/vg_libpthread.c
@@ -1941,20 +1941,10 @@
 
    /* Either timeout == NULL, meaning wait indefinitely, or timeout !=
       NULL, in which case ms_end holds the end time. */
+
    while (1) {
-      if (timeout) {
-         VALGRIND_MAGIC_SEQUENCE(ms_now, 0xFFFFFFFF /* default */,
-                                 VG_USERREQ__READ_MILLISECOND_TIMER,
-                                 0, 0, 0, 0);
-         my_assert(ms_now != 0xFFFFFFFF);
-         if (ms_now >= ms_end) {
-            /* timeout; nothing interesting happened. */
-            if (rfds) FD_ZERO(rfds);
-            if (wfds) FD_ZERO(wfds);
-            if (xfds) FD_ZERO(xfds);
-            return 0;
-         }
-      }
+
+      /* First, do a return-immediately select(). */
 
       /* These could be trashed each time round the loop, so restore
          them each time. */
@@ -1983,6 +1973,10 @@
          if (xfds) *xfds = xfds_copy;
          return res;
       }
+
+      /* Nothing interesting happened, so we go to sleep for a
+         while. */
+
       /* fprintf(stderr, "MY_SELECT: nanosleep\n"); */
       /* nanosleep and go round again */
       nanosleep_interval.tv_sec  = 0;
@@ -1997,6 +1991,23 @@
          * (__errno_location()) = EINTR;
          return -1;
       }
+
+      /* Sleeping finished.  If a finite timeout, check to see if it
+         has expired yet. */
+      if (timeout) {
+         VALGRIND_MAGIC_SEQUENCE(ms_now, 0xFFFFFFFF /* default */,
+                                 VG_USERREQ__READ_MILLISECOND_TIMER,
+                                 0, 0, 0, 0);
+         my_assert(ms_now != 0xFFFFFFFF);
+         if (ms_now >= ms_end) {
+            /* timeout; nothing interesting happened. */
+            if (rfds) FD_ZERO(rfds);
+            if (wfds) FD_ZERO(wfds);
+            if (xfds) FD_ZERO(xfds);
+            return 0;
+         }
+      }
+
    }
 }
 
@@ -2055,9 +2066,38 @@
 
    /* Either timeout < 0, meaning wait indefinitely, or timeout > 0,
       in which case t_end holds the end time. */
+
    my_assert(__timeout != 0);
 
    while (1) {
+
+      /* Do a return-immediately poll. */
+
+      res = my_do_syscall3(__NR_poll, (int)__fds, __nfds, 0 );
+      if (is_kerror(res)) {
+         /* Some kind of error.  Set errno and return.  */
+         * (__errno_location()) = -res;
+         return -1;
+      }
+      if (res > 0) {
+         /* One or more fds is ready.  Return now. */
+         return res;
+      }
+
+      /* Nothing interesting happened, so we go to sleep for a
+         while. */
+
+      /* fprintf(stderr, "MY_POLL: nanosleep\n"); */
+      /* nanosleep and go round again */
+      nanosleep_interval.tv_sec  = 0;
+      nanosleep_interval.tv_nsec = 51 * 1000 * 1000; /* 51 milliseconds */
+      /* It's critical here that valgrind's nanosleep implementation
+         is nonblocking. */
+      (void)my_do_syscall2(__NR_nanosleep, 
+                           (int)(&nanosleep_interval), (int)NULL);
+
+      /* Sleeping finished.  If a finite timeout, check to see if it
+         has expired yet. */
       if (__timeout > 0) {
          VALGRIND_MAGIC_SEQUENCE(ms_now, 0xFFFFFFFF /* default */,
                                  VG_USERREQ__READ_MILLISECOND_TIMER,
@@ -2071,25 +2111,6 @@
          }
       }
 
-      /* Do a return-immediately poll. */
-      res = my_do_syscall3(__NR_poll, (int)__fds, __nfds, 0 );
-      if (is_kerror(res)) {
-         /* Some kind of error.  Set errno and return.  */
-         * (__errno_location()) = -res;
-         return -1;
-      }
-      if (res > 0) {
-         /* One or more fds is ready.  Return now. */
-         return res;
-      }
-      /* fprintf(stderr, "MY_POLL: nanosleep\n"); */
-      /* nanosleep and go round again */
-      nanosleep_interval.tv_sec  = 0;
-      nanosleep_interval.tv_nsec = 51 * 1000 * 1000; /* 51 milliseconds */
-      /* It's critical here that valgrind's nanosleep implementation
-         is nonblocking. */
-      (void)my_do_syscall2(__NR_nanosleep, 
-                           (int)(&nanosleep_interval), (int)NULL);
    }
 }