summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sustrik <sustrik@250bpm.com>2011-07-21 18:54:27 +0200
committerMartin Sustrik <sustrik@250bpm.com>2011-07-21 18:54:27 +0200
commita1e09facb2438f6487b32cdcfff21f0ece735460 (patch)
treefebb8297a36455286d412596af0696c26aadc129
parent72a793f78ae6c7b544d4c19530c01e8dfd23ccf5 (diff)
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 <sustrik@250bpm.com>
-rw-r--r--doc/zmq_send.txt3
-rw-r--r--include/zmq.h1
-rwxr-xr-xsrc/router.cpp33
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 ();