Commit 8259c519 authored by Eelis van der Weegen's avatar Eelis van der Weegen

Problem: Program crashes if memory allocation in socket_poller_t::rebuild fails.

Solution: Report memory allocation failure as ENOMEM so applications can handle it gracefully.

Fixes #3427.
parent cdc4b8c6
...@@ -223,6 +223,8 @@ On _zmq_poller_add_fd_, _zmq_poller_modify_fd_ and _zmq_poller_remove_fd_: ...@@ -223,6 +223,8 @@ On _zmq_poller_add_fd_, _zmq_poller_modify_fd_ and _zmq_poller_remove_fd_:
The _fd_ specified was the retired fd. The _fd_ specified was the retired fd.
On _zmq_poller_wait_ and _zmq_poller_wait_all_: On _zmq_poller_wait_ and _zmq_poller_wait_all_:
*ENOMEM*::
Necessary resources could not be allocated.
*ETERM*:: *ETERM*::
At least one of the registered objects is a 'socket' whose associated 0MQ At least one of the registered objects is a 'socket' whose associated 0MQ
'context' was terminated. 'context' was terminated.
......
...@@ -260,7 +260,7 @@ int zmq::socket_poller_t::remove_fd (fd_t fd_) ...@@ -260,7 +260,7 @@ int zmq::socket_poller_t::remove_fd (fd_t fd_)
return 0; return 0;
} }
void zmq::socket_poller_t::rebuild () int zmq::socket_poller_t::rebuild ()
{ {
_use_signaler = false; _use_signaler = false;
_pollset_size = 0; _pollset_size = 0;
...@@ -287,10 +287,15 @@ void zmq::socket_poller_t::rebuild () ...@@ -287,10 +287,15 @@ void zmq::socket_poller_t::rebuild ()
} }
if (_pollset_size == 0) if (_pollset_size == 0)
return; return 0;
_pollfds = static_cast<pollfd *> (malloc (_pollset_size * sizeof (pollfd))); _pollfds = static_cast<pollfd *> (malloc (_pollset_size * sizeof (pollfd)));
alloc_assert (_pollfds);
if (!_pollfds) {
errno = ENOMEM;
_need_rebuild = true;
return -1;
}
int item_nbr = 0; int item_nbr = 0;
...@@ -390,6 +395,8 @@ void zmq::socket_poller_t::rebuild () ...@@ -390,6 +395,8 @@ void zmq::socket_poller_t::rebuild ()
} }
#endif #endif
return 0;
} }
void zmq::socket_poller_t::zero_trail_events ( void zmq::socket_poller_t::zero_trail_events (
...@@ -523,8 +530,11 @@ int zmq::socket_poller_t::wait (zmq::socket_poller_t::event_t *events_, ...@@ -523,8 +530,11 @@ int zmq::socket_poller_t::wait (zmq::socket_poller_t::event_t *events_,
return -1; return -1;
} }
if (_need_rebuild) if (_need_rebuild) {
rebuild (); int rc = rebuild ();
if (rc == -1)
return -1;
}
if (unlikely (_pollset_size == 0)) { if (unlikely (_pollset_size == 0)) {
// We'll report an error (timed out) as if the list was non-empty and // We'll report an error (timed out) as if the list was non-empty and
......
...@@ -101,7 +101,7 @@ class socket_poller_t ...@@ -101,7 +101,7 @@ class socket_poller_t
uint64_t &now_, uint64_t &now_,
uint64_t &end_, uint64_t &end_,
bool &first_pass_); bool &first_pass_);
void rebuild (); int rebuild ();
// Used to check whether the object is a socket_poller. // Used to check whether the object is a socket_poller.
uint32_t _tag; uint32_t _tag;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment