aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-12-07 03:03:31 +0000
committerMiles Bader <miles@gnu.org>1995-12-07 03:03:31 +0000
commit0c7b844d256598d5fda1692894fc769ca9f18450 (patch)
treec9c2a19b6db840dbed4a117755976231267d1439
parent(__select): Swap size args to mach_msg. (diff)
downloadglibc-0c7b844d256598d5fda1692894fc769ca9f18450.tar.gz
glibc-0c7b844d256598d5fda1692894fc769ca9f18450.tar.bz2
glibc-0c7b844d256598d5fda1692894fc769ca9f18450.zip
(__select): Still clear the user's bits for an fd when SELECT_RETURNED isn't set. Only clear bits in the user's fdsets -- those needing to be set should be already. Use SELECT_ALL in appropiate places. (SELECT_ALL): New macro.
-rw-r--r--sysdeps/mach/hurd/select.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/sysdeps/mach/hurd/select.c b/sysdeps/mach/hurd/select.c
index 3de8f209d2..84e89c5c05 100644
--- a/sysdeps/mach/hurd/select.c
+++ b/sysdeps/mach/hurd/select.c
@@ -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;