diff --git a/doc/zmq_poller.txt b/doc/zmq_poller.txt index 1394410f..a2b076d5 100644 --- a/doc/zmq_poller.txt +++ b/doc/zmq_poller.txt @@ -256,7 +256,8 @@ At least one of the registered objects is a 'socket' whose associated 0MQ 'context' was terminated. *EFAULT*:: The provided 'events' was NULL, or 'poller' did not point to a valid poller, -or there are no registered objects and 'timeout' was negative. +or there are no registered objects or all event subscriptions are disabled +and 'timeout' was negative. *EINTR*:: The operation was interrupted by delivery of a signal before any events were available. diff --git a/src/socket_poller.cpp b/src/socket_poller.cpp index c761646e..f1f3f43b 100644 --- a/src/socket_poller.cpp +++ b/src/socket_poller.cpp @@ -548,6 +548,11 @@ int zmq::socket_poller_t::wait (zmq::socket_poller_t::event_t *events_, } if (unlikely (_pollset_size == 0)) { + if (timeout_ < 0) { + // Fail instead of trying to sleep forever + errno = EFAULT; + return -1; + } // We'll report an error (timed out) as if the list was non-empty and // no event occurred within the specified timeout. Otherwise the caller // needs to check the return value AND the event to avoid using the diff --git a/tests/test_poller.cpp b/tests/test_poller.cpp index 2662b414..24d13d57 100644 --- a/tests/test_poller.cpp +++ b/tests/test_poller.cpp @@ -512,6 +512,17 @@ void call_poller_wait_all_empty_with_timeout_fails (void *poller_, zmq_poller_wait_all (poller_, &event, 0, -1)); } +void call_poller_wait_all_inf_disabled_fails (void *poller_, void *socket_) +{ + TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_add (poller_, socket_, NULL, 0)); + + zmq_poller_event_t events[1]; + TEST_ASSERT_FAILURE_ERRNO (EAGAIN, + zmq_poller_wait_all (poller_, events, 1, 0)); + TEST_ASSERT_FAILURE_ERRNO (EFAULT, + zmq_poller_wait_all (poller_, events, 1, -1)); +} + TEST_CASE_FUNC_PARAM (call_poller_wait_empty_with_timeout_fails, test_with_empty_poller) TEST_CASE_FUNC_PARAM (call_poller_wait_empty_without_timeout_fails, @@ -522,6 +533,8 @@ TEST_CASE_FUNC_PARAM (call_poller_wait_all_empty_without_timeout_fails, test_with_empty_poller) TEST_CASE_FUNC_PARAM (call_poller_wait_all_empty_with_timeout_fails, test_with_empty_poller) +TEST_CASE_FUNC_PARAM (call_poller_wait_all_inf_disabled_fails, + test_with_empty_poller) void test_poll_basic () { @@ -695,6 +708,7 @@ int main (void) RUN_TEST (test_call_poller_wait_all_empty_negative_count_fails); RUN_TEST (test_call_poller_wait_all_empty_without_timeout_fails); RUN_TEST (test_call_poller_wait_all_empty_with_timeout_fails); + RUN_TEST (test_call_poller_wait_all_inf_disabled_fails); RUN_TEST (test_call_poller_fd_no_signaler); RUN_TEST (test_call_poller_fd);