mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 15:41:05 +08:00
Run-time checking for context & socket validity added
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
This commit is contained in:
parent
e62686aca5
commit
b96fe15bb6
@ -56,8 +56,8 @@ The requested 'address' was not local.
|
|||||||
The requested 'address' specifies a nonexistent interface.
|
The requested 'address' specifies a nonexistent interface.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
*EMTHREAD*::
|
*EMTHREAD*::
|
||||||
No I/O thread is available to accomplish the task.
|
No I/O thread is available to accomplish the task.
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ return `-1` and set 'errno' to one of the values defined below.
|
|||||||
|
|
||||||
ERRORS
|
ERRORS
|
||||||
------
|
------
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
|
@ -54,8 +54,8 @@ The requested 'transport' protocol is not supported.
|
|||||||
The requested 'transport' protocol is not compatible with the socket type.
|
The requested 'transport' protocol is not compatible with the socket type.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
*EMTHREAD*::
|
*EMTHREAD*::
|
||||||
No I/O thread is available to accomplish the task.
|
No I/O thread is available to accomplish the task.
|
||||||
|
|
||||||
|
@ -359,8 +359,8 @@ _option_value_, as specified by _option_len_, is insufficient for storing the
|
|||||||
option value.
|
option value.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
*EINTR*::
|
*EINTR*::
|
||||||
The operation was interrupted by delivery of a signal.
|
The operation was interrupted by delivery of a signal.
|
||||||
|
|
||||||
|
@ -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.
|
_messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
*EINTR*::
|
*EINTR*::
|
||||||
The operation was interrupted by delivery of a signal before a message was
|
The operation was interrupted by delivery of a signal before a message was
|
||||||
available.
|
available.
|
||||||
|
@ -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.
|
_messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
*EINTR*::
|
*EINTR*::
|
||||||
The operation was interrupted by delivery of a signal before the message was
|
The operation was interrupted by delivery of a signal before the message was
|
||||||
sent.
|
sent.
|
||||||
|
@ -310,8 +310,8 @@ The requested option _option_name_ is unknown, or the requested _option_len_ or
|
|||||||
_option_value_ is invalid.
|
_option_value_ is invalid.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
The 0MQ 'context' associated with the specified 'socket' was terminated.
|
||||||
*EFAULT*::
|
*ENOTSOCK*::
|
||||||
The provided 'socket' was not valid (NULL).
|
The provided 'socket' was invalid.
|
||||||
*EINTR*::
|
*EINTR*::
|
||||||
The operation was interrupted by delivery of a signal.
|
The operation was interrupted by delivery of a signal.
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ ERRORS
|
|||||||
*EINVAL*::
|
*EINVAL*::
|
||||||
The requested socket 'type' is invalid.
|
The requested socket 'type' is invalid.
|
||||||
*EFAULT*::
|
*EFAULT*::
|
||||||
The provided 'context' was not valid (NULL).
|
The provided 'context' is invalid.
|
||||||
*ETERM*::
|
*ETERM*::
|
||||||
The context specified was terminated.
|
The context specified was terminated.
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ return `-1` and set 'errno' to one of the values defined below.
|
|||||||
ERRORS
|
ERRORS
|
||||||
------
|
------
|
||||||
*EFAULT*::
|
*EFAULT*::
|
||||||
The provided 'context' was not valid (NULL).
|
The provided 'context' was invalid.
|
||||||
*EINTR*::
|
*EINTR*::
|
||||||
Termination was interrupted by a signal. It can be restarted if needed.
|
Termination was interrupted by a signal. It can be restarted if needed.
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
zmq::ctx_t::ctx_t (uint32_t io_threads_) :
|
zmq::ctx_t::ctx_t (uint32_t io_threads_) :
|
||||||
|
tag (0xbadcafe0),
|
||||||
terminating (false)
|
terminating (false)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@ -78,6 +79,11 @@ zmq::ctx_t::ctx_t (uint32_t io_threads_) :
|
|||||||
zmq_assert (rc == 0);
|
zmq_assert (rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool zmq::ctx_t::check_tag ()
|
||||||
|
{
|
||||||
|
return tag == 0xbadcafe0;
|
||||||
|
}
|
||||||
|
|
||||||
zmq::ctx_t::~ctx_t ()
|
zmq::ctx_t::~ctx_t ()
|
||||||
{
|
{
|
||||||
// Check that there are no remaining sockets.
|
// Check that there are no remaining sockets.
|
||||||
@ -99,6 +105,9 @@ zmq::ctx_t::~ctx_t ()
|
|||||||
// needed as mailboxes themselves were deallocated with their
|
// needed as mailboxes themselves were deallocated with their
|
||||||
// corresponding io_thread/socket objects.
|
// corresponding io_thread/socket objects.
|
||||||
free (slots);
|
free (slots);
|
||||||
|
|
||||||
|
// Remove the tag, so that the object is considered dead.
|
||||||
|
tag = 0xdeadbeef;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::ctx_t::terminate ()
|
int zmq::ctx_t::terminate ()
|
||||||
|
@ -60,6 +60,9 @@ namespace zmq
|
|||||||
// of I/O thread pool to create.
|
// of I/O thread pool to create.
|
||||||
ctx_t (uint32_t io_threads_);
|
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
|
// 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
|
// no more sockets open it'll cause all the infrastructure to be shut
|
||||||
// down. If there are open sockets still, the deallocation happens
|
// down. If there are open sockets still, the deallocation happens
|
||||||
@ -98,6 +101,9 @@ namespace zmq
|
|||||||
|
|
||||||
~ctx_t ();
|
~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
|
// Sockets belonging to this context. We need the list so that
|
||||||
// we can notify the sockets when zmq_term() is called. The sockets
|
// we can notify the sockets when zmq_term() is called. The sockets
|
||||||
// will return ETERM then.
|
// will return ETERM then.
|
||||||
|
@ -61,6 +61,11 @@
|
|||||||
#include "xpub.hpp"
|
#include "xpub.hpp"
|
||||||
#include "xsub.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_,
|
zmq::socket_base_t *zmq::socket_base_t::create (int type_, class ctx_t *parent_,
|
||||||
uint32_t tid_)
|
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_) :
|
zmq::socket_base_t::socket_base_t (ctx_t *parent_, uint32_t tid_) :
|
||||||
own_t (parent_, tid_),
|
own_t (parent_, tid_),
|
||||||
|
tag (0xbaddecaf),
|
||||||
ctx_terminated (false),
|
ctx_terminated (false),
|
||||||
destroyed (false),
|
destroyed (false),
|
||||||
last_tsc (0),
|
last_tsc (0),
|
||||||
@ -126,6 +132,9 @@ zmq::socket_base_t::~socket_base_t ()
|
|||||||
sessions_sync.lock ();
|
sessions_sync.lock ();
|
||||||
zmq_assert (sessions.empty ());
|
zmq_assert (sessions.empty ());
|
||||||
sessions_sync.unlock ();
|
sessions_sync.unlock ();
|
||||||
|
|
||||||
|
// Mark the socket as dead.
|
||||||
|
tag = 0xdeadbeef;
|
||||||
}
|
}
|
||||||
|
|
||||||
zmq::mailbox_t *zmq::socket_base_t::get_mailbox ()
|
zmq::mailbox_t *zmq::socket_base_t::get_mailbox ()
|
||||||
|
@ -50,6 +50,9 @@ namespace zmq
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Returns false if object is not a socket.
|
||||||
|
bool check_tag ();
|
||||||
|
|
||||||
// Create a socket of a specified type.
|
// Create a socket of a specified type.
|
||||||
static socket_base_t *create (int type_, class ctx_t *parent_,
|
static socket_base_t *create (int type_, class ctx_t *parent_,
|
||||||
uint32_t tid_);
|
uint32_t tid_);
|
||||||
@ -136,6 +139,9 @@ namespace zmq
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// Used to check whether the object is a socket.
|
||||||
|
uint32_t tag;
|
||||||
|
|
||||||
// If true, associated context was already terminated.
|
// If true, associated context was already terminated.
|
||||||
bool ctx_terminated;
|
bool ctx_terminated;
|
||||||
|
|
||||||
|
32
src/zmq.cpp
32
src/zmq.cpp
@ -261,7 +261,7 @@ void *zmq_init (int io_threads_)
|
|||||||
|
|
||||||
int zmq_term (void *ctx_)
|
int zmq_term (void *ctx_)
|
||||||
{
|
{
|
||||||
if (!ctx_) {
|
if (!ctx_ || !((zmq::ctx_t*) ctx_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ int zmq_term (void *ctx_)
|
|||||||
|
|
||||||
void *zmq_socket (void *ctx_, int type_)
|
void *zmq_socket (void *ctx_, int type_)
|
||||||
{
|
{
|
||||||
if (!ctx_) {
|
if (!ctx_ || !((zmq::ctx_t*) ctx_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -296,8 +296,8 @@ void *zmq_socket (void *ctx_, int type_)
|
|||||||
|
|
||||||
int zmq_close (void *s_)
|
int zmq_close (void *s_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
((zmq::socket_base_t*) s_)->close ();
|
((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_,
|
int zmq_setsockopt (void *s_, int option_, const void *optval_,
|
||||||
size_t optvallen_)
|
size_t optvallen_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (((zmq::socket_base_t*) s_)->setsockopt (option_, optval_,
|
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_)
|
int zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (((zmq::socket_base_t*) s_)->getsockopt (option_, optval_,
|
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_)
|
int zmq_bind (void *s_, const char *addr_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (((zmq::socket_base_t*) s_)->bind (addr_));
|
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_)
|
int zmq_connect (void *s_, const char *addr_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (((zmq::socket_base_t*) s_)->connect (addr_));
|
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_)
|
int zmq_sendmsg (void *s_, zmq_msg_t *msg_, int flags_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int sz = (int) zmq_msg_size (msg_);
|
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_)
|
int zmq_recvmsg (void *s_, zmq_msg_t *msg_, int flags_)
|
||||||
{
|
{
|
||||||
if (!s_) {
|
if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) {
|
||||||
errno = EFAULT;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int rc = (((zmq::socket_base_t*) s_)->recv (msg_, flags_));
|
int rc = (((zmq::socket_base_t*) s_)->recv (msg_, flags_));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user