Problem: sockets can be created after calling zmq_ctx_shutdown

Solution: fix handling of _starting and _terminate flags

Add tests for this situation.

Clarify documentation of zmq_ctx_shutdown and zmq_socket.

Fixes #3792
This commit is contained in:
Simon Giesecke
2020-01-26 18:04:06 +01:00
parent 349e3e21db
commit 36a8df2f8c
4 changed files with 63 additions and 17 deletions

View File

@@ -232,16 +232,18 @@ int zmq::ctx_t::shutdown ()
{
scoped_lock_t locker (_slot_sync);
if (!_starting && !_terminating) {
if (!_terminating) {
_terminating = true;
// Send stop command to sockets so that any blocking calls
// can be interrupted. If there are no sockets we can ask reaper
// thread to stop.
for (sockets_t::size_type i = 0; i != _sockets.size (); i++)
_sockets[i]->stop ();
if (_sockets.empty ())
_reaper->stop ();
if (!_starting) {
// Send stop command to sockets so that any blocking calls
// can be interrupted. If there are no sockets we can ask reaper
// thread to stop.
for (sockets_t::size_type i = 0; i != _sockets.size (); i++)
_sockets[i]->stop ();
if (_sockets.empty ())
_reaper->stop ();
}
}
return 0;
@@ -471,17 +473,18 @@ zmq::socket_base_t *zmq::ctx_t::create_socket (int type_)
{
scoped_lock_t locker (_slot_sync);
if (unlikely (_starting)) {
if (!start ())
return NULL;
}
// Once zmq_ctx_term() was called, we can't create new sockets.
// Once zmq_ctx_term() or zmq_ctx_shutdown() was called, we can't create
// new sockets.
if (_terminating) {
errno = ETERM;
return NULL;
}
if (unlikely (_starting)) {
if (!start ())
return NULL;
}
// If max_sockets limit was reached, return error.
if (_empty_slots.empty ()) {
errno = EMFILE;