From 37e6334d5f6b6412ba6f225ac394b2f08f9b22a2 Mon Sep 17 00:00:00 2001 From: or17191 Date: Sat, 18 Jul 2020 19:07:55 +0300 Subject: [PATCH] Bugfix: socket_t move assignment doesn't initialize ctxptr Until now, we only assigned the _handle on `zmq::socket_t::operator=(socket_t&&)`. This manifests when trying to monitor a socket initialized by that constructor. To avoid changing the public interface of the socket_t class, we tested for the specific monitor usecase, since it's the only class accessing zmq::socke_t::ctxptr. NOTE: When running the new unit-test without the fix, it might hang on `zmq_socket_monitor(socket_, NULL, 0)`. We haven't figured out the cause for that, but we deemed it unimportant (or at least out of scope). --- tests/monitor.cpp | 15 +++++++++++++++ zmq.hpp | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/tests/monitor.cpp b/tests/monitor.cpp index bb54ca1..a17b9c4 100644 --- a/tests/monitor.cpp +++ b/tests/monitor.cpp @@ -142,4 +142,19 @@ TEST_CASE("monitor init abort", "[monitor]") monitor.abort(); thread.join(); } + + +TEST_CASE("monitor from move assigned socket", "[monitor]") +{ + zmq::context_t ctx; + zmq::socket_t sock; + sock = std::move([&ctx] { + zmq::socket_t sock(ctx, ZMQ_DEALER); + return sock; + }()); + zmq::monitor_t monitor1; + monitor1.init(sock, "inproc://monitor-client"); + // On failure, this test might hang indefinitely instead of immediately + // failing +} #endif diff --git a/zmq.hpp b/zmq.hpp index 54212a5..e259555 100644 --- a/zmq.hpp +++ b/zmq.hpp @@ -2103,6 +2103,7 @@ class socket_t : public detail::socket_base { close(); std::swap(_handle, rhs._handle); + std::swap(ctxptr, rhs.ctxptr); return *this; } #endif @@ -2121,6 +2122,7 @@ class socket_t : public detail::socket_base int rc = zmq_close(_handle); ZMQ_ASSERT(rc == 0); _handle = ZMQ_NULLPTR; + ctxptr = ZMQ_NULLPTR; } void swap(socket_t &other) ZMQ_NOTHROW @@ -2143,6 +2145,9 @@ class socket_t : public detail::socket_base { if (_handle == ZMQ_NULLPTR) throw error_t(); + if (ctxptr == ZMQ_NULLPTR) + throw error_t(); + } };