From a2af3d18cc81a13ae894d9068cf0c20192bb132a Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Sun, 11 Feb 2018 13:15:37 +0100 Subject: [PATCH 1/3] Problem: unittest_poller fails for poll_t Solution: fixed behaviour in corner cases --- src/poll.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/poll.cpp b/src/poll.cpp index 608ddec5..0eb9a51d 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -52,6 +52,7 @@ zmq::poll_t::poll_t (const zmq::ctx_t &ctx_) : zmq::poll_t::~poll_t () { + stop (); worker.stop (); } @@ -141,6 +142,11 @@ void zmq::poll_t::loop () // Execute any due timers. int timeout = (int) execute_timers (); + if (pollset.empty ()) { + // TODO yield? or sleep for timeout? + continue; + } + // Wait for events. int rc = poll (&pollset[0], pollset.size (), timeout ? timeout : -1); if (rc == -1) { From 2f27bcd74bcd335f8dac4eb97b7c92e1d2309c9d Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Sun, 11 Feb 2018 13:45:40 +0100 Subject: [PATCH 2/3] Problem: assertion failure in poll_t::poll if timer_event retired a pollset entry Solution: clean up retired entries before poll --- src/poll.cpp | 27 ++++++++++++++++----------- src/poll.hpp | 2 ++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/poll.cpp b/src/poll.cpp index 0eb9a51d..64248cf5 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -142,6 +142,8 @@ void zmq::poll_t::loop () // Execute any due timers. int timeout = (int) execute_timers (); + cleanup_retired (); + if (pollset.empty ()) { // TODO yield? or sleep for timeout? continue; @@ -174,20 +176,23 @@ void zmq::poll_t::loop () if (pollset[i].revents & POLLIN) fd_table[pollset[i].fd].events->in_event (); } + } +} - // Clean up the pollset and update the fd_table accordingly. - if (retired) { - pollset_t::size_type i = 0; - while (i < pollset.size ()) { - if (pollset[i].fd == retired_fd) - pollset.erase (pollset.begin () + i); - else { - fd_table[pollset[i].fd].index = i; - i++; - } +void zmq::poll_t::cleanup_retired () +{ + // Clean up the pollset and update the fd_table accordingly. + if (retired) { + pollset_t::size_type i = 0; + while (i < pollset.size ()) { + if (pollset[i].fd == retired_fd) + pollset.erase (pollset.begin () + i); + else { + fd_table[pollset[i].fd].index = i; + i++; } - retired = false; } + retired = false; } } diff --git a/src/poll.hpp b/src/poll.hpp index 08c6b544..59904ae5 100644 --- a/src/poll.hpp +++ b/src/poll.hpp @@ -79,6 +79,8 @@ class poll_t : public poller_base_t // Main event loop. void loop (); + void cleanup_retired(); + // Reference to ZMQ context. const ctx_t &ctx; From 5873894c8364332f89902e5e39f0bde2c22bef1e Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Sun, 11 Feb 2018 12:19:20 +0100 Subject: [PATCH 3/3] Problem: wrong assertion macro used on Windows Solution: use wsa_assert instead of errno_assert --- src/poll.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/poll.cpp b/src/poll.cpp index 64248cf5..39ea5ff7 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -151,10 +151,14 @@ void zmq::poll_t::loop () // Wait for events. int rc = poll (&pollset[0], pollset.size (), timeout ? timeout : -1); +#ifdef ZMQ_HAVE_WINDOWS + wsa_assert (rc != SOCKET_ERROR); +#else if (rc == -1) { errno_assert (errno == EINTR); continue; } +#endif // If there are no events (i.e. it's a timeout) there's no point // in checking the pollset.