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:
commit
afd5d9f721
37
src/poll.cpp
37
src/poll.cpp
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user