Hi,
Attached is the first patch for a 3-way split of hurdselect.c into three
cases: DELAY, POLL, SELECT leading to a more POSIX conforming POLL. The
Hurd servers pflocal and pfinet are already prepared for this update.
Starting point is the hurdselect.c created by all Debian patches applied
up to eglibc-2.13-38 + 3 additional patches:
[PATCH,HURD] hurdselect: remove dead code:
http://lists.gnu.org/archive/html/bug-hurd/2013-01/msg00004.html
unsubmitted-select-EINTR.diff
unsubmitted-setitimer_fix.diff
The patch does the following:
1) Introduce the ispoll enum
2) Create the three cases: DELAY, POLL, SELECT
3) Move the msg union definition to the definitions in the beginning.
4) Move the definitions of IO_SELECT_REPLY_MSGID and inttype to the
beginning.
Subsequent patches will be made relative to this patch if accepted.
--- hurdselect.c-38+patches 2013-01-22 16:09:25.000000000 +0100
+++ hurdselect_step1_1.c 2013-01-22 17:33:12.000000000 +0100
@@ -68,12 +68,74 @@ _hurd_select (int nfds,
assert (sizeof (union typeword) == sizeof (mach_msg_type_t));
assert (sizeof (uint32_t) == sizeof (mach_msg_type_t));
+ enum {
+ DELAY = -1,
+ SELECT = 0,
+ POLL = 1
+ } ispoll;
+
+ if (nfds == 0)
+ ispoll = DELAY;
+ else if (pollfds)
+ ispoll = POLL;
+ else
+ ispoll = SELECT;
+
+ union
+ {
+ mach_msg_header_t head;
+#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
+ struct
+ {
+ mach_msg_header_t head;
+ NDR_record_t ndr;
+ error_t err;
+ } error;
+ struct
+ {
+ mach_msg_header_t head;
+ NDR_record_t ndr;
+ error_t err;
+ int result;
+ mach_msg_trailer_t trailer;
+ } success;
+#else
+ struct
+ {
+ mach_msg_header_t head;
+ union typeword err_type;
+ error_t err;
+ } error;
+ struct
+ {
+ mach_msg_header_t head;
+ union typeword err_type;
+ error_t err;
+ union typeword result_type;
+ int result;
+ } success;
+#endif
+ } msg;
+ mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
+ error_t msgerr;
+
+#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
+#ifdef MACH_MSG_TYPE_BIT
+ const union typeword inttype =
+ { type:
+ { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
+ };
+#endif
+
if (nfds < 0 || nfds > FD_SETSIZE)
{
errno = EINVAL;
return -1;
}
+ if (nfds > _hurd_dtablesize)
+ nfds = _hurd_dtablesize;
+
if (timeout != NULL)
{
if (timeout->tv_sec < 0 || timeout->tv_nsec < 0)
@@ -123,13 +185,10 @@ _hurd_select (int nfds,
{
const int fd = (int) d[i].io_port;
- if (fd < _hurd_dtablesize)
- {
d[i].cell = _hurd_dtable[fd];
d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
if (d[i].io_port != MACH_PORT_NULL)
continue;
- }
/* If one descriptor is bogus, we fail completely. */
while (i-- > 0)
@@ -174,9 +233,6 @@ _hurd_select (int nfds,
HURD_CRITICAL_BEGIN;
__mutex_lock (&_hurd_dtable_lock);
- if (nfds > _hurd_dtablesize)
- nfds = _hurd_dtablesize;
-
/* Collect the ports for interesting FDs. */
firstfd = lastfd = -1;
for (i = 0; i < nfds; ++i)
@@ -296,57 +352,12 @@ _hurd_select (int nfds,
{
/* Now wait for io_select_reply messages on PORT,
timing out as appropriate. */
-
- union
- {
- mach_msg_header_t head;
-#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
- struct
- {
- mach_msg_header_t head;
- NDR_record_t ndr;
- error_t err;
- } error;
- struct
- {
- mach_msg_header_t head;
- NDR_record_t ndr;
- error_t err;
- int result;
- mach_msg_trailer_t trailer;
- } success;
-#else
- struct
- {
- mach_msg_header_t head;
- union typeword err_type;
- error_t err;
- } error;
- struct
- {
- mach_msg_header_t head;
- union typeword err_type;
- error_t err;
- union typeword result_type;
- int result;
- } success;
-#endif
- } msg;
- mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
- error_t msgerr;
while ((msgerr = __mach_msg (&msg.head,
MACH_RCV_MSG | MACH_RCV_INTERRUPT | options,
0, sizeof msg, portset, to,
MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
{
/* We got a message. Decode it. */
-#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
-#ifdef MACH_MSG_TYPE_BIT
- const union typeword inttype =
- { type:
- { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
- };
-#endif
if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
msg.head.msgh_size >= sizeof msg.error &&
!(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&