summaryrefslogtreecommitdiff
path: root/hurd/hurdselect.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2016-06-09 01:34:49 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-06-09 01:34:49 +0200
commite827fc3efb03d684766be5d1a9961dd87d925a90 (patch)
tree418b04dad1b9df89a274d3733e8f117eba254fb3 /hurd/hurdselect.c
parentc1f50227bb78c74ad6ced84d8d2db2aacfe77ef5 (diff)
move gettimeofday call out of the critical section, to avoid getting an EINTR
Diffstat (limited to 'hurd/hurdselect.c')
-rw-r--r--hurd/hurdselect.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c
index 22faac9b0c..070ac1a0cc 100644
--- a/hurd/hurdselect.c
+++ b/hurd/hurdselect.c
@@ -120,6 +120,7 @@ _hurd_select (int nfds,
if (pollfds)
{
+ int error = 0;
/* Collect interesting descriptors from the user's `pollfd' array.
We do a first pass that reads the user's array before taking
any locks. The second pass then only touches our own stack,
@@ -165,30 +166,37 @@ _hurd_select (int nfds,
/* Bogus descriptor, make it EBADF already. */
d[i].error = EBADF;
d[i].type = SELECT_ERROR;
-
- /* And set timeout to 0. */
- {
- struct timeval now;
- err = __gettimeofday(&now, NULL);
- if (err)
- {
- err = errno;
- while (i-- > 0)
- if (d[i].type & ~SELECT_ERROR != 0)
- _hurd_port_free (&d[i].cell->port, &d[i].ulink,
- d[i].io_port);
- errno = err;
- return -1;
- }
- ts.tv_sec = now.tv_sec;
- ts.tv_nsec = now.tv_usec * 1000;
- reply_msgid = IO_SELECT_TIMEOUT_REPLY_MSGID;
- }
+ error = 1;
}
__mutex_unlock (&_hurd_dtable_lock);
HURD_CRITICAL_END;
+ if (error)
+ {
+ /* Set timeout to 0. */
+ struct timeval now;
+ err = __gettimeofday(&now, NULL);
+ if (err)
+ {
+ /* Really bad luck. */
+ err = errno;
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_dtable_lock);
+ while (i-- > 0)
+ if (d[i].type & ~SELECT_ERROR != 0)
+ _hurd_port_free (&d[i].cell->port, &d[i].ulink,
+ d[i].io_port);
+ __mutex_unlock (&_hurd_dtable_lock);
+ HURD_CRITICAL_END;
+ errno = err;
+ return -1;
+ }
+ ts.tv_sec = now.tv_sec;
+ ts.tv_nsec = now.tv_usec * 1000;
+ reply_msgid = IO_SELECT_TIMEOUT_REPLY_MSGID;
+ }
+
lastfd = i - 1;
firstfd = i == 0 ? lastfd : 0;
}