From 096007c574a33ef5ea2b4665e20f68c21b883f61 Mon Sep 17 00:00:00 2001 From: Richard Newton Date: Fri, 21 Aug 2015 10:06:54 +0100 Subject: [PATCH] Fix zmq crash when calling shutdown with a pending inproc socket connect --- src/ctx.cpp | 9 +++++++-- tests/test_inproc_connect.cpp | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/ctx.cpp b/src/ctx.cpp index 4bbead7c..d6240a35 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -126,15 +126,20 @@ zmq::ctx_t::~ctx_t () int zmq::ctx_t::terminate () { - // Connect up any pending inproc connections, otherwise we will hang + slot_sync.lock(); + + bool saveTerminating = terminating; + terminating = false; + + // Connect up any pending inproc connections, otherwise we will hang pending_connections_t copy = pending_connections; for (pending_connections_t::iterator p = copy.begin (); p != copy.end (); ++p) { zmq::socket_base_t *s = create_socket (ZMQ_PAIR); s->bind (p->first.c_str ()); s->close (); } + terminating = saveTerminating; - slot_sync.lock (); if (!starting) { #ifdef HAVE_FORK diff --git a/tests/test_inproc_connect.cpp b/tests/test_inproc_connect.cpp index 106765db..b282cf77 100644 --- a/tests/test_inproc_connect.cpp +++ b/tests/test_inproc_connect.cpp @@ -471,6 +471,27 @@ void test_unbind () assert (rc == 0); } +void test_shutdown_during_pend () +{ + void *ctx = zmq_ctx_new (); + assert (ctx); + + // Connect first + void *connectSocket = zmq_socket (ctx, ZMQ_PAIR); + assert (connectSocket); + int rc = zmq_connect (connectSocket, "inproc://cbb"); + assert (rc == 0); + + zmq_ctx_shutdown (ctx); + + // Cleanup + rc = zmq_close (connectSocket); + assert (rc == 0); + + rc = zmq_ctx_term (ctx); + assert (rc == 0); +} + int main (void) { setup_test_environment (); @@ -484,6 +505,7 @@ int main (void) test_identity (); test_connect_only (); test_unbind (); + test_shutdown_during_pend (); return 0; }