From a1e09facb2438f6487b32cdcfff21f0ece735460 Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Thu, 21 Jul 2011 18:54:27 +0200 Subject: ROUTER socket reports error when message cannot be routed Till now, message was silently dropped if it was sent to a non-existent peer. Now, ECANTROUTE error is returned. Signed-off-by: Martin Sustrik --- doc/zmq_send.txt | 3 +++ include/zmq.h | 1 + src/router.cpp | 33 +++++++++++++++++++-------------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/doc/zmq_send.txt b/doc/zmq_send.txt index 2b51953..c631113 100644 --- a/doc/zmq_send.txt +++ b/doc/zmq_send.txt @@ -79,6 +79,9 @@ The provided 'socket' was invalid. *EINTR*:: The operation was interrupted by delivery of a signal before the message was sent. +*ECANTROUTE*:: +Message cannot be routed to the destination specified as the peer is either +dead or disconnected. This error makes sense only with ZMQ_ROUTER socket. EXAMPLE diff --git a/include/zmq.h b/include/zmq.h index d18e4e5..2c95219 100644 --- a/include/zmq.h +++ b/include/zmq.h @@ -107,6 +107,7 @@ ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch); #define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) #define ETERM (ZMQ_HAUSNUMERO + 53) #define EMTHREAD (ZMQ_HAUSNUMERO + 54) +#define ECANTROUTE (ZMQ_HAUSNUMERO + 55) /* This function retrieves the errno as it is known to 0MQ library. The goal */ /* of this function is to make the code 100% portable, including where 0MQ */ diff --git a/src/router.cpp b/src/router.cpp index 3428c87..9f0dbc6 100755 --- a/src/router.cpp +++ b/src/router.cpp @@ -137,24 +137,29 @@ int zmq::router_t::xsend (msg_t *msg_, int flags_) more_out = true; // Find the pipe associated with the peer ID stored in the prefix. - // If there's no such pipe just silently ignore the message. - zmq_assert (msg_->size () == 4); + if (unlikely (msg_->size () != 4)) { + errno = ECANTROUTE; + return -1; + } uint32_t peer_id = get_uint32 ((unsigned char*) msg_->data ()); outpipes_t::iterator it = outpipes.find (peer_id); + if (unlikely (it == outpipes.end ())) { + errno = ECANTROUTE; + return -1; + } - if (it != outpipes.end ()) { - current_out = it->second.pipe; - msg_t empty; - int rc = empty.init (); - errno_assert (rc == 0); - if (!current_out->check_write (&empty)) { - it->second.active = false; - more_out = false; - current_out = NULL; - } - rc = empty.close (); - errno_assert (rc == 0); + // Check whether the pipe is available for writing. + current_out = it->second.pipe; + msg_t empty; + int rc = empty.init (); + errno_assert (rc == 0); + if (!current_out->check_write (&empty)) { + it->second.active = false; + more_out = false; + current_out = NULL; } + rc = empty.close (); + errno_assert (rc == 0); } int rc = msg_->close (); -- cgit v1.2.3