diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-06-09 01:35:58 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-06-09 01:35:58 +0200 |
commit | c995a7c7c2bf31eb5c302e3147080e2ca48f1c5f (patch) | |
tree | 1075bdbf288a19034ccb48a9e59862c74ffd7a6b | |
parent | 5ebf5d24aa206f7fd10aeb89c2ac6db7116939d5 (diff) | |
parent | e827fc3efb03d684766be5d1a9961dd87d925a90 (diff) |
Merge branch 't/poll_errors_fixes' into refs/top-bases/tschwinge/Roger_Whittaker
-rw-r--r-- | hurd/hurdselect.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c index ed1f448198..e58eff4c6e 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,31 +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. */ - { - /* TODO:move now to avoid gettimeofday in the middle of critical section */ - 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; } |