>From b96fe15bb666e59728b6aa02f28c5838020f6bf3 Mon Sep 17 00:00:00 2001
From: Martin Sustrik <[email protected]>
Date: Sat, 9 Apr 2011 09:35:34 +0200
Subject: [PATCH 1/2] Run-time checking for context & socket validity added

Signed-off-by: Martin Sustrik <[email protected]>
---
 doc/zmq_bind.txt       |    4 ++--
 doc/zmq_close.txt      |    4 ++--
 doc/zmq_connect.txt    |    4 ++--
 doc/zmq_getsockopt.txt |    4 ++--
 doc/zmq_recv.txt       |    4 ++--
 doc/zmq_send.txt       |    4 ++--
 doc/zmq_setsockopt.txt |    4 ++--
 doc/zmq_socket.txt     |    2 +-
 doc/zmq_term.txt       |    2 +-
 src/ctx.cpp            |    9 +++++++++
 src/ctx.hpp            |    6 ++++++
 src/socket_base.cpp    |    9 +++++++++
 src/socket_base.hpp    |    6 ++++++
 src/zmq.cpp            |   32 ++++++++++++++++----------------
 14 files changed, 62 insertions(+), 32 deletions(-)

diff --git a/doc/zmq_bind.txt b/doc/zmq_bind.txt
index 23c3134..da20d78 100644
--- a/doc/zmq_bind.txt
+++ b/doc/zmq_bind.txt
@@ -56,8 +56,8 @@ The requested 'address' was not local.
 The requested 'address' specifies a nonexistent interface.
 *ETERM*::
 The 0MQ 'context' associated with the specified 'socket' was terminated.
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 *EMTHREAD*::
 No I/O thread is available to accomplish the task.
 
diff --git a/doc/zmq_close.txt b/doc/zmq_close.txt
index fe3bde5..9f026a3 100644
--- a/doc/zmq_close.txt
+++ b/doc/zmq_close.txt
@@ -34,8 +34,8 @@ return `-1` and set 'errno' to one of the values defined below.
 
 ERRORS
 ------
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 
 
 SEE ALSO
diff --git a/doc/zmq_connect.txt b/doc/zmq_connect.txt
index a95f716..d25270f 100644
--- a/doc/zmq_connect.txt
+++ b/doc/zmq_connect.txt
@@ -54,8 +54,8 @@ The requested 'transport' protocol is not supported.
 The requested 'transport' protocol is not compatible with the socket type.
 *ETERM*::
 The 0MQ 'context' associated with the specified 'socket' was terminated.
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 *EMTHREAD*::
 No I/O thread is available to accomplish the task.
 
diff --git a/doc/zmq_getsockopt.txt b/doc/zmq_getsockopt.txt
index c5dd968..926cf32 100644
--- a/doc/zmq_getsockopt.txt
+++ b/doc/zmq_getsockopt.txt
@@ -359,8 +359,8 @@ _option_value_, as specified by _option_len_, is insufficient for storing the
 option value.
 *ETERM*::
 The 0MQ 'context' associated with the specified 'socket' was terminated.
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 *EINTR*::
 The operation was interrupted by delivery of a signal.
 
diff --git a/doc/zmq_recv.txt b/doc/zmq_recv.txt
index 1588c64..fe601ba 100644
--- a/doc/zmq_recv.txt
+++ b/doc/zmq_recv.txt
@@ -63,8 +63,8 @@ socket types that switch between several states, such as ZMQ_REP.  See the
 _messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
 *ETERM*::
 The 0MQ 'context' associated with the specified 'socket' was terminated.
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 *EINTR*::
 The operation was interrupted by delivery of a signal before a message was
 available.
diff --git a/doc/zmq_send.txt b/doc/zmq_send.txt
index c8d6f33..4561ae0 100644
--- a/doc/zmq_send.txt
+++ b/doc/zmq_send.txt
@@ -69,8 +69,8 @@ socket types that switch between several states, such as ZMQ_REP.  See the
 _messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
 *ETERM*::
 The 0MQ 'context' associated with the specified 'socket' was terminated.
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 *EINTR*::
 The operation was interrupted by delivery of a signal before the message was
 sent.
diff --git a/doc/zmq_setsockopt.txt b/doc/zmq_setsockopt.txt
index 48afbfc..f5c873e 100644
--- a/doc/zmq_setsockopt.txt
+++ b/doc/zmq_setsockopt.txt
@@ -310,8 +310,8 @@ The requested option _option_name_ is unknown, or the requested _option_len_ or
 _option_value_ is invalid.
 *ETERM*::
 The 0MQ 'context' associated with the specified 'socket' was terminated.
-*EFAULT*::
-The provided 'socket' was not valid (NULL).
+*ENOTSOCK*::
+The provided 'socket' was invalid.
 *EINTR*::
 The operation was interrupted by delivery of a signal.
 
diff --git a/doc/zmq_socket.txt b/doc/zmq_socket.txt
index e8c4253..a319518 100644
--- a/doc/zmq_socket.txt
+++ b/doc/zmq_socket.txt
@@ -309,7 +309,7 @@ ERRORS
 *EINVAL*::
 The requested socket 'type' is invalid.
 *EFAULT*::
-The provided 'context' was not valid (NULL).
+The provided 'context' is invalid.
 *ETERM*::
 The context specified was terminated.
 
diff --git a/doc/zmq_term.txt b/doc/zmq_term.txt
index d3914db..64e32ca 100644
--- a/doc/zmq_term.txt
+++ b/doc/zmq_term.txt
@@ -46,7 +46,7 @@ return `-1` and set 'errno' to one of the values defined below.
 ERRORS
 ------
 *EFAULT*::
-The provided 'context' was not valid (NULL).
+The provided 'context' was invalid.
 *EINTR*::
 Termination was interrupted by a signal. It can be restarted if needed.
 
diff --git a/src/ctx.cpp b/src/ctx.cpp
index 9cbb9de..2758729 100644
--- a/src/ctx.cpp
+++ b/src/ctx.cpp
@@ -36,6 +36,7 @@
 #endif
 
 zmq::ctx_t::ctx_t (uint32_t io_threads_) :
+    tag (0xbadcafe0),
     terminating (false)
 {
     int rc;
@@ -78,6 +79,11 @@ zmq::ctx_t::ctx_t (uint32_t io_threads_) :
     zmq_assert (rc == 0);
 }
 
+bool zmq::ctx_t::check_tag ()
+{
+    return tag == 0xbadcafe0;
+}
+
 zmq::ctx_t::~ctx_t ()
 {
     //  Check that there are no remaining sockets.
@@ -99,6 +105,9 @@ zmq::ctx_t::~ctx_t ()
     //  needed as mailboxes themselves were deallocated with their
     //  corresponding io_thread/socket objects.
     free (slots);
+
+    //  Remove the tag, so that the object is considered dead.
+    tag = 0xdeadbeef;
 }
 
 int zmq::ctx_t::terminate ()
diff --git a/src/ctx.hpp b/src/ctx.hpp
index c6ea4ce..33d5dad 100644
--- a/src/ctx.hpp
+++ b/src/ctx.hpp
@@ -60,6 +60,9 @@ namespace zmq
         //  of I/O thread pool to create.
         ctx_t (uint32_t io_threads_);
 
+        //  Returns false if object is not a context.
+        bool check_tag ();
+
         //  This function is called when user invokes zmq_term. If there are
         //  no more sockets open it'll cause all the infrastructure to be shut
         //  down. If there are open sockets still, the deallocation happens
@@ -98,6 +101,9 @@ namespace zmq
 
         ~ctx_t ();
 
+        //  Used to check whether the object is a context.
+        uint32_t tag;
+
         //  Sockets belonging to this context. We need the list so that
         //  we can notify the sockets when zmq_term() is called. The sockets
         //  will return ETERM then.
diff --git a/src/socket_base.cpp b/src/socket_base.cpp
index b1d1142..c9b5c31 100644
--- a/src/socket_base.cpp
+++ b/src/socket_base.cpp
@@ -61,6 +61,11 @@
 #include "xpub.hpp"
 #include "xsub.hpp"
 
+bool zmq::socket_base_t::check_tag ()
+{
+    return tag == 0xbaddecaf;
+}
+
 zmq::socket_base_t *zmq::socket_base_t::create (int type_, class ctx_t *parent_,
     uint32_t tid_)
 {
@@ -110,6 +115,7 @@ zmq::socket_base_t *zmq::socket_base_t::create (int type_, class ctx_t *parent_,
 
 zmq::socket_base_t::socket_base_t (ctx_t *parent_, uint32_t tid_) :
     own_t (parent_, tid_),
+    tag (0xbaddecaf),
     ctx_terminated (false),
     destroyed (false),
     last_tsc (0),
@@ -126,6 +132,9 @@ zmq::socket_base_t::~socket_base_t ()
     sessions_sync.lock ();
     zmq_assert (sessions.empty ());
     sessions_sync.unlock ();
+
+    //  Mark the socket as dead.
+    tag = 0xdeadbeef;
 }
 
 zmq::mailbox_t *zmq::socket_base_t::get_mailbox ()
diff --git a/src/socket_base.hpp b/src/socket_base.hpp
index 15ac83c..333cddd 100644
--- a/src/socket_base.hpp
+++ b/src/socket_base.hpp
@@ -50,6 +50,9 @@ namespace zmq
 
     public:
 
+        //  Returns false if object is not a socket.
+        bool check_tag ();
+
         //  Create a socket of a specified type.
         static socket_base_t *create (int type_, class ctx_t *parent_,
             uint32_t tid_);
@@ -136,6 +139,9 @@ namespace zmq
 
     private:
 
+        //  Used to check whether the object is a socket.
+        uint32_t tag;
+
         //  If true, associated context was already terminated.
         bool ctx_terminated;
 
diff --git a/src/zmq.cpp b/src/zmq.cpp
index c65e166..0f536ac 100644
--- a/src/zmq.cpp
+++ b/src/zmq.cpp
@@ -261,7 +261,7 @@ void *zmq_init (int io_threads_)
 
 int zmq_term (void *ctx_)
 {
-    if (!ctx_) {
+    if (!ctx_ || !((zmq::ctx_t*) ctx_)->check_tag ()) {
         errno = EFAULT;
         return -1;
     }
@@ -287,7 +287,7 @@ int zmq_term (void *ctx_)
 
 void *zmq_socket (void *ctx_, int type_)
 {
-    if (!ctx_) {
+    if (!ctx_ || !((zmq::ctx_t*) ctx_)->check_tag ()) {
         errno = EFAULT;
         return NULL;
     }
@@ -296,8 +296,8 @@ void *zmq_socket (void *ctx_, int type_)
 
 int zmq_close (void *s_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     ((zmq::socket_base_t*) s_)->close ();
@@ -307,8 +307,8 @@ int zmq_close (void *s_)
 int zmq_setsockopt (void *s_, int option_, const void *optval_,
     size_t optvallen_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     return (((zmq::socket_base_t*) s_)->setsockopt (option_, optval_,
@@ -317,8 +317,8 @@ int zmq_setsockopt (void *s_, int option_, const void *optval_,
 
 int zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     return (((zmq::socket_base_t*) s_)->getsockopt (option_, optval_,
@@ -327,8 +327,8 @@ int zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_)
 
 int zmq_bind (void *s_, const char *addr_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     return (((zmq::socket_base_t*) s_)->bind (addr_));
@@ -336,8 +336,8 @@ int zmq_bind (void *s_, const char *addr_)
 
 int zmq_connect (void *s_, const char *addr_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     return (((zmq::socket_base_t*) s_)->connect (addr_));
@@ -393,8 +393,8 @@ int zmq_recv (void *s_, void *buf_, size_t len_, int flags_)
 
 int zmq_sendmsg (void *s_, zmq_msg_t *msg_, int flags_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     int sz = (int) zmq_msg_size (msg_);
@@ -406,8 +406,8 @@ int zmq_sendmsg (void *s_, zmq_msg_t *msg_, int flags_)
 
 int zmq_recvmsg (void *s_, zmq_msg_t *msg_, int flags_)
 {
-    if (!s_) {
-        errno = EFAULT;
+    if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
+        errno = ENOTSOCK;
         return -1;
     }
     int rc = (((zmq::socket_base_t*) s_)->recv (msg_, flags_));
-- 
1.7.0.4

>From 0839cceac9dd29cc64cd9a634b9d3340cfbf3bbe Mon Sep 17 00:00:00 2001
From: Martin Sustrik <[email protected]>
Date: Sat, 9 Apr 2011 09:46:59 +0200
Subject: [PATCH 2/2] Missing ENOTSOCK added on Win32

Signed-off-by: Martin Sustrik <[email protected]>
---
 include/zmq.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/zmq.h b/include/zmq.h
index 01c9d80..e6fb60d 100644
--- a/include/zmq.h
+++ b/include/zmq.h
@@ -98,6 +98,9 @@ ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
 #ifndef EINPROGRESS
 #define EINPROGRESS (ZMQ_HAUSNUMERO + 8)
 #endif
+#ifndef ENOTSOCK
+#define ENOTSOCK (ZMQ_HAUSNUMERO + 9)
+#endif
 
 /*  Native 0MQ error codes.                                                   */
 #define EFSM (ZMQ_HAUSNUMERO + 51)
-- 
1.7.0.4

_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to