@@ -39,6 +39,19 @@ class context_t {
3939 zmq_proto_assert (rc == 0 );
4040 }
4141
42+ // Implement move constructor
43+ context_t (context_t &&other) noexcept : context(other.context) {
44+ other.context = NULL ; // Set the moved-from context to NULL
45+ }
46+
47+ context_t &operator =(context_t &&other) noexcept {
48+ if (this != &other && other.context != NULL ) {
49+ context = other.context ;
50+ other.context = NULL ; // Set the moved-from context to NULL
51+ }
52+ return *this ;
53+ }
54+
4255 int init (int n_threads) {
4356 context = zmq_ctx_new ();
4457 zmq_proto_assert (context != NULL );
@@ -56,6 +69,12 @@ class context_t {
5669 void *zmq_handle () { return context; }
5770
5871 ~context_t () {
72+ // Avoid double close
73+ if (context == NULL ) {
74+ return ;
75+ }
76+ printf (" [ %s:%d %s ] Closing context %p\n " , __FILE__, __LINE__, __func__,
77+ context);
5978 int rc;
6079 do {
6180 rc = zmq_ctx_destroy (context);
@@ -119,11 +138,29 @@ template <socket_type_t socket_type> class socket_t {
119138 }
120139 }
121140
141+ // Implement move constructor and assignment operator
142+ socket_t (socket_t &&other) noexcept : socket(other.socket) {
143+ other.socket = NULL ; // Set the moved-from socket to NULL
144+ }
145+ socket_t &operator =(socket_t &&other) noexcept {
146+ if (this != &other && other.socket != NULL ) {
147+ socket = other.socket ;
148+ other.socket = NULL ; // Set the moved-from socket to NULL
149+ }
150+ return *this ;
151+ }
152+
122153 void *zmq_handle () const { return socket; }
123154
124155 void *zmq_handle () { return socket; }
125156
126157 ~socket_t () {
158+ // Avoid double close
159+ if (socket == NULL ) {
160+ return ;
161+ }
162+ printf (" [ %s:%d %s ] Closing socket %p\n " , __FILE__, __LINE__, __func__,
163+ socket);
127164 int rc = zmq_close (socket);
128165 zmq_proto_assert (rc == 0 );
129166
@@ -152,6 +189,12 @@ class msg_t {
152189 int rc = zmq_msg_close (&msg);
153190 zmq_proto_assert (rc == 0 );
154191 }
192+
193+ // Disallow copy constructor, assignment operator and move operations
194+ msg_t (const msg_t &) = delete ;
195+ msg_t &operator =(const msg_t &) = delete ;
196+ msg_t (msg_t &&) = delete ;
197+ msg_t &operator =(msg_t &&) = delete ;
155198};
156199
157200// helpers:
@@ -324,10 +367,10 @@ int recv_more(::google::protobuf::MessageLite &proto_msg,
324367
325368/*
326369 receives two parts of a multipart message. Matches first with type name and
327- parses second into proto errno: EAGAIN if the inbound message queue was empty
328- errno: EBADMSG if the type name didn't match
329- errno: EOPNOTSUPP if there were no more message parts to receive after first
330- part errno: EPROTO if the proto could not be parsed / did not match
370+ parses second into proto errno: EAGAIN if the inbound message queue was
371+ empty errno: EBADMSG if the type name didn't match errno: EOPNOTSUPP if
372+ there were no more message parts to receive after first part errno: EPROTO
373+ if the proto could not be parsed / did not match
331374*/
332375template <socket_type_t socket_type>
333376int recv (::google::protobuf::MessageLite &proto_msg,
0 commit comments