mirror of
https://github.com/zeromq/libzmq.git
synced 2025-02-01 14:55:59 +01:00
zmq_poll doesn't exit when infinite timeout is set and interrupt occurs
This commit is contained in:
parent
3a69cca386
commit
f24955519a
54
src/zmq.cpp
54
src/zmq.cpp
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user