(__select): Still clear the user's bits for an fd when SELECT_RETURNED isn't set...
authorMiles Bader <miles@gnu.org>
Thu, 7 Dec 1995 03:03:31 +0000 (03:03 +0000)
committerMiles Bader <miles@gnu.org>
Thu, 7 Dec 1995 03:03:31 +0000 (03:03 +0000)
sysdeps/mach/hurd/select.c

index 3de8f20..84e89c5 100644 (file)
@@ -23,6 +23,12 @@ Cambridge, MA 02139, USA.  */
 #include <stdlib.h>
 #include <string.h>
 
+/* All user select types.  */
+#define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG)
+
+/* Used to record that a particular select rpc returned. Must be distinct
+   from SELECT_ALL (which better not have the high bit set).  */
+#define SELECT_RETURNED ((SELECT_ALL << 1) & ~SELECT_ALL)
 
 /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
    readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
@@ -137,8 +143,7 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
                /* We got an answer.  This is not necessarily the answer to
                    the query we sent just now.  It may correspond to any
                    prior query which timed out before its answer arrived.  */
-               if (tag < 0 || tag > i ||
-                   (type & (SELECT_READ|SELECT_URG|SELECT_WRITE)) == 0)
+               if (tag < 0 || tag > i || (type & SELECT_ALL) == 0)
                  /* This is not a proper answer to any query we have yet
                      made.  */
                  err = EGRATUITOUS;
@@ -146,6 +151,7 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
                  {
                    /* Some port is ready.  TAG tells us which.  */
                    types[tag] &= type;
+                   types[tag] |= SELECT_RETURNED;
                    ++got;
                  }
                break;
@@ -213,19 +219,16 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
                       *(int *) &msg.success.tag_type != *(int *) &inttype ||
                       *(int *) &msg.success.result_type != *(int *) &inttype)
                __mach_msg_destroy (&msg);
-             else if ((msg.success.result &
-                       (SELECT_READ|SELECT_WRITE|SELECT_URG)) == 0 ||
+             else if ((msg.success.result & SELECT_ALL) == 0 ||
                       msg.success.tag < firstfd || msg.success.tag > lastfd)
                err = EGRATUITOUS;
              else
                {
                  /* This is a winning io_select_reply message!
                     Record the readiness it indicates and send a reply.  */
-                 if (types[msg.success.tag] == 0)
-                   /* This descriptor is ready and it was not before,
-                      so we increment our count of ready descriptors.  */
-                   ++got;
-                 types[msg.success.tag] |= msg.success.result;
+                 types[msg.success.tag] &= msg.success.result;
+                 types[msg.success.tag] |= SELECT_RETURNED;
+                 ++got;
                }
            }
 
@@ -272,24 +275,21 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
   if (err)
     return __hurd_fail (err);
 
-  /* Set the user bitarrays.  */
+  /* Set the user bitarrays.  We only ever have to clear bits, as all desired
+     ones are initially set.  */
   for (i = 0; i < nfds; ++i)
     {
-      if (readfds != NULL)
-       if (types[i] & SELECT_READ)
-         FD_SET (i, readfds);
-       else
-         FD_CLR (i, readfds);
-      if (writefds != NULL)
-       if (types[i] & SELECT_WRITE)
-         FD_SET (i, writefds);
-       else
-         FD_CLR (i, writefds);
-      if (exceptfds != NULL)
-       if (types[i] & SELECT_URG)
-         FD_SET (i, exceptfds);
-       else
-         FD_CLR (i, exceptfds);
+      int type = types[i];
+
+      if ((type & SELECT_RETURNED) == 0)
+       type = 0;
+
+      if (readfds != NULL && (type & SELECT_READ) == 0)
+       FD_CLR (i, readfds);
+      if (writefds != NULL && (type & SELECT_WRITE) == 0)
+       FD_CLR (i, writefds);
+      if (exceptfds != NULL && (type & SELECT_URG) == 0)
+       FD_CLR (i, exceptfds);
     }
 
   return got;