zmq_poll doesn't exit when infinite timeout is set and interrupt occurs

This commit is contained in:
Martin Sustrik 2010-02-22 18:19:26 +01:00
parent 3a69cca386
commit f24955519a

View File

@ -383,11 +383,11 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
// prevent exiting on any events that may already been signaled on // prevent exiting on any events that may already been signaled on
// 0MQ sockets. // 0MQ sockets.
int rc = poll (pollfds, npollfds, 0); int rc = poll (pollfds, npollfds, 0);
if (rc == -1 && errno == EINTR) { if (rc == -1 && errno == EINTR && timeout_ >= 0) {
free (pollfds); free (pollfds);
return 0; return 0;
} }
errno_assert (rc >= 0); errno_assert (rc >= 0 || (rc == -1 && errno == EINTR));
int timeout = timeout_ > 0 ? timeout_ / 1000 : -1; int timeout = timeout_ > 0 ? timeout_ / 1000 : -1;
int nevents = 0; int nevents = 0;
@ -427,14 +427,23 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
// If there's at least one event, or if we are asked not to block, // If there's at least one event, or if we are asked not to block,
// return immediately. // return immediately.
if (nevents || !timeout) if (nevents || !timeout_)
break; break;
// Wait for events. // Wait for events. Ignore interrupts if there's infinite timeout.
rc = poll (pollfds, npollfds, timeout); while (true) {
if (rc == -1 && errno == EINTR) rc = poll (pollfds, npollfds, timeout);
if (rc == -1 && errno == EINTR) {
if (timeout_ < 0)
continue;
else {
rc = 0;
break;
}
}
errno_assert (rc >= 0);
break; break;
errno_assert (rc >= 0); }
// If timeout was hit with no events signaled, return zero. // If timeout was hit with no events signaled, return zero.
if (rc == 0) if (rc == 0)
@ -523,7 +532,9 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
#if defined ZMQ_HAVE_WINDOWS #if defined ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR); wsa_assert (rc != SOCKET_ERROR);
#else #else
errno_assert (rc != -1 || errno != EINTR); if (rc == -1 && errno == EINTR && timeout_ >= 0)
return 0;
errno_assert (rc >= 0 || (rc == -1 && errno == EINTR));
#endif #endif
while (true) { while (true) {
@ -562,17 +573,28 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
if (nevents || (timeout.tv_sec == 0 && timeout.tv_usec == 0)) if (nevents || (timeout.tv_sec == 0 && timeout.tv_usec == 0))
break; break;
// Wait for events. // Wait for events. Ignore interrupts if there's infinite timeout.
memcpy (&inset, &pollset_in, sizeof (fd_set)); while (true) {
memcpy (&outset, &pollset_out, sizeof (fd_set)); memcpy (&inset, &pollset_in, sizeof (fd_set));
memcpy (&errset, &pollset_err, sizeof (fd_set)); memcpy (&outset, &pollset_out, sizeof (fd_set));
int rc = select (maxfd, &inset, &outset, &errset, memcpy (&errset, &pollset_err, sizeof (fd_set));
block ? NULL : &timeout); int rc = select (maxfd, &inset, &outset, &errset,
block ? NULL : &timeout);
#if defined ZMQ_HAVE_WINDOWS #if defined ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR); wsa_assert (rc != SOCKET_ERROR);
#else #else
errno_assert (rc != -1 || errno != EINTR); if (rc == -1 && errno == EINTR) {
if (timeout_ < 0)
continue;
else {
rc = 0;
break;
}
}
errno_assert (rc >= 0);
#endif #endif
break;
}
// If timeout was hit with no events signaled, return zero. // If timeout was hit with no events signaled, return zero.
if (rc == 0) if (rc == 0)