Commit 75809b27 authored by Pieter Hintjens's avatar Pieter Hintjens

Fixed issue LIBZMQ-345 - race condition in ctx.socket/term allows segfault

parent 3b483a8d
...@@ -84,11 +84,11 @@ zmq::ctx_t::~ctx_t () ...@@ -84,11 +84,11 @@ zmq::ctx_t::~ctx_t ()
int zmq::ctx_t::terminate () int zmq::ctx_t::terminate ()
{ {
slot_sync.lock ();
if (!starting) { if (!starting) {
// Check whether termination was already underway, but interrupted and now // Check whether termination was already underway, but interrupted and now
// restarted. // restarted.
slot_sync.lock ();
bool restarted = terminating; bool restarted = terminating;
terminating = true; terminating = true;
slot_sync.unlock (); slot_sync.unlock ();
...@@ -116,8 +116,8 @@ int zmq::ctx_t::terminate () ...@@ -116,8 +116,8 @@ int zmq::ctx_t::terminate ()
zmq_assert (cmd.type == command_t::done); zmq_assert (cmd.type == command_t::done);
slot_sync.lock (); slot_sync.lock ();
zmq_assert (sockets.empty ()); zmq_assert (sockets.empty ());
slot_sync.unlock ();
} }
slot_sync.unlock ();
// Deallocate the resources. // Deallocate the resources.
delete this; delete this;
...@@ -163,10 +163,10 @@ int zmq::ctx_t::get (int option_) ...@@ -163,10 +163,10 @@ int zmq::ctx_t::get (int option_)
zmq::socket_base_t *zmq::ctx_t::create_socket (int type_) zmq::socket_base_t *zmq::ctx_t::create_socket (int type_)
{ {
slot_sync.lock ();
if (unlikely (starting)) { if (unlikely (starting)) {
starting = false; starting = false;
// Initialise the array of mailboxes. Additional three slots are for // Initialise the array of mailboxes. Additional three slots are for
// zmq_term thread and reaper thread. // zmq_term thread and reaper thread.
opt_sync.lock (); opt_sync.lock ();
...@@ -203,8 +203,6 @@ zmq::socket_base_t *zmq::ctx_t::create_socket (int type_) ...@@ -203,8 +203,6 @@ zmq::socket_base_t *zmq::ctx_t::create_socket (int type_)
} }
} }
slot_sync.lock ();
// Once zmq_term() was called, we can't create new sockets. // Once zmq_term() was called, we can't create new sockets.
if (terminating) { if (terminating) {
slot_sync.unlock (); slot_sync.unlock ();
...@@ -237,7 +235,6 @@ zmq::socket_base_t *zmq::ctx_t::create_socket (int type_) ...@@ -237,7 +235,6 @@ zmq::socket_base_t *zmq::ctx_t::create_socket (int type_)
slots [slot] = s->get_mailbox (); slots [slot] = s->get_mailbox ();
slot_sync.unlock (); slot_sync.unlock ();
return s; return s;
} }
......
...@@ -126,7 +126,7 @@ namespace zmq ...@@ -126,7 +126,7 @@ namespace zmq
// Synchronisation of accesses to global slot-related data: // Synchronisation of accesses to global slot-related data:
// sockets, empty_slots, terminating. It also synchronises // sockets, empty_slots, terminating. It also synchronises
// access to zombie sockets as such (as oposed to slots) and provides // access to zombie sockets as such (as opposed to slots) and provides
// a memory barrier to ensure that all CPU cores see the same data. // a memory barrier to ensure that all CPU cores see the same data.
mutex_t slot_sync; mutex_t slot_sync;
......
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