0
0
mirror of https://github.com/zeromq/libzmq.git synced 2025-01-14 17:58:01 +08:00

Merge pull request #2939 from sigiesec/fix-poll-timer-event-retiring

Fixed a deadlock and an assertion failure in poll_t
This commit is contained in:
Luca Boccassi 2018-02-11 17:06:36 +00:00 committed by GitHub
commit afd5d9f721
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 11 deletions

View File

@ -52,6 +52,7 @@ zmq::poll_t::poll_t (const zmq::ctx_t &ctx_) :
zmq::poll_t::~poll_t () zmq::poll_t::~poll_t ()
{ {
stop ();
worker.stop (); worker.stop ();
} }
@ -141,12 +142,23 @@ void zmq::poll_t::loop ()
// Execute any due timers. // Execute any due timers.
int timeout = (int) execute_timers (); int timeout = (int) execute_timers ();
cleanup_retired ();
if (pollset.empty ()) {
// TODO yield? or sleep for timeout?
continue;
}
// Wait for events. // Wait for events.
int rc = poll (&pollset[0], pollset.size (), timeout ? timeout : -1); int rc = poll (&pollset[0], pollset.size (), timeout ? timeout : -1);
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
if (rc == -1) { if (rc == -1) {
errno_assert (errno == EINTR); errno_assert (errno == EINTR);
continue; continue;
} }
#endif
// If there are no events (i.e. it's a timeout) there's no point // If there are no events (i.e. it's a timeout) there's no point
// in checking the pollset. // in checking the pollset.
@ -168,20 +180,23 @@ void zmq::poll_t::loop ()
if (pollset[i].revents & POLLIN) if (pollset[i].revents & POLLIN)
fd_table[pollset[i].fd].events->in_event (); fd_table[pollset[i].fd].events->in_event ();
} }
}
}
// Clean up the pollset and update the fd_table accordingly. void zmq::poll_t::cleanup_retired ()
if (retired) { {
pollset_t::size_type i = 0; // Clean up the pollset and update the fd_table accordingly.
while (i < pollset.size ()) { if (retired) {
if (pollset[i].fd == retired_fd) pollset_t::size_type i = 0;
pollset.erase (pollset.begin () + i); while (i < pollset.size ()) {
else { if (pollset[i].fd == retired_fd)
fd_table[pollset[i].fd].index = i; pollset.erase (pollset.begin () + i);
i++; else {
} fd_table[pollset[i].fd].index = i;
i++;
} }
retired = false;
} }
retired = false;
} }
} }

View File

@ -79,6 +79,8 @@ class poll_t : public poller_base_t
// Main event loop. // Main event loop.
void loop (); void loop ();
void cleanup_retired();
// Reference to ZMQ context. // Reference to ZMQ context.
const ctx_t &ctx; const ctx_t &ctx;