diff --git a/doc/zmq_poller.txt b/doc/zmq_poller.txt index 8fad43c2..fed45f5a 100644 --- a/doc/zmq_poller.txt +++ b/doc/zmq_poller.txt @@ -21,11 +21,16 @@ SYNOPSIS *int zmq_poller_modify_fd (void *'poller', int 'fd', short 'events');* *int zmq_poller_remove_fd (void *'poller', int 'fd');* +*int zmq_poller_wait (void *'poller', + zmq_poller_event_t *'event', + long 'timeout');* *int zmq_poller_wait_all (void *'poller', zmq_poller_event_t *'events', int 'n_events', long 'timeout');* +*int zmq_poller_fd (void *'poller');* + DESCRIPTION ----------- The _zmq_poller_*_ functions provide a mechanism for applications to multiplex @@ -124,6 +129,10 @@ The client does therefore not need to initialize the contents of the events array before a call to _zmq_poller_wait_all_. It is unspecified whether the the remaining elements of 'events' are written to by _zmq_poller_wait_all_. +_zmq_poller_fd_ returns the file descriptor associated with the zmq_poller. +The zmq_poller is only guaranteed to have a file descriptor if +at least one thread-safe socket is currently registered. + EVENT TYPES ----------- @@ -237,6 +246,11 @@ available. *EAGAIN*:: No registered event was signalled before the timeout was reached. +On _zmq_poller_fd: +*EINVAL*:: +The poller has no associated file descriptor. +*EFAULT*:: +The provided 'poller' did not point to a valid poller. EXAMPLE ------- diff --git a/src/zmq.cpp b/src/zmq.cpp index 521d9939..5dc1fc40 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -1280,7 +1280,13 @@ int zmq_poller_wait_all (void *poller_, int zmq_poller_fd (void *poller_) { - return static_cast (poller_)->signaler_fd (); + if (!poller_ + || !(static_cast (poller_)->check_tag ())) { + errno = EFAULT; + return -1; + } else { + return static_cast (poller_)->signaler_fd (); + } } // Peer-specific state diff --git a/tests/test_poller.cpp b/tests/test_poller.cpp index c6afb92c..8170bc75 100644 --- a/tests/test_poller.cpp +++ b/tests/test_poller.cpp @@ -195,6 +195,12 @@ void test_null_poller_pointers_wait_all_indirect () EFAULT, zmq_poller_wait_all (&null_poller, &event, 1, 0)); } +void test_null_poller_pointer_poller_fd () +{ + void *null_poller = NULL; + TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_poller_fd (&null_poller)); +} + void test_null_socket_pointers () { void *poller = zmq_poller_new (); @@ -257,6 +263,40 @@ void test_with_valid_poller (extra_poller_func_t extra_func_) test_context_socket_close (socket); } +void test_call_poller_fd_no_signaler () +{ + void *socket = test_context_socket (ZMQ_PAIR); + + void *poller = zmq_poller_new (); + TEST_ASSERT_NOT_NULL (poller); + + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_poller_add (poller, socket, NULL, ZMQ_POLLIN)); + + TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_poller_fd (poller)); + + TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_destroy (&poller)); + + test_context_socket_close (socket); +} + +void test_call_poller_fd () +{ + void *socket = test_context_socket (ZMQ_CLIENT); + + void *poller = zmq_poller_new (); + TEST_ASSERT_NOT_NULL (poller); + + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_poller_add (poller, socket, NULL, ZMQ_POLLIN)); + + TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_fd (poller)); + + TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_destroy (&poller)); + + test_context_socket_close (socket); +} + void call_poller_wait_null_event_fails (void *poller_) { TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_poller_wait (poller_, NULL, 0)); @@ -626,6 +666,7 @@ int main (void) RUN_TEST (test_null_poller_pointers_wait_indirect); RUN_TEST (test_null_poller_pointers_wait_all_direct); RUN_TEST (test_null_poller_pointers_wait_all_indirect); + RUN_TEST (test_null_poller_pointer_poller_fd); RUN_TEST (test_null_socket_pointers); @@ -652,6 +693,9 @@ int main (void) 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_fd_no_signaler); + RUN_TEST (test_call_poller_fd); + RUN_TEST (test_poll_basic); RUN_TEST (test_poll_fd); RUN_TEST (test_poll_client_server);