Allow blocking while connect() is completing

This patch, salvaged from a trainwreck accidental merge earlier, adds a
new sockopt, ZMQ_DELAY_ATTACH_ON_CONNECT which prevents a end point
being available to push messages to until it has fully connected, making
connect work more like bind. This also applies to reconnecting sockets,
which may cause message loss of in-queue messages, so it is sensible to
use this in conjunction with a low HWM and potentially an alternative
acknowledgement path.

Notes on most of the individual commits can be found the repository log.
This commit is contained in:
Ian Barber
2012-06-12 15:34:48 +01:00
parent 409d5e8fff
commit e5904e63ce
11 changed files with 117 additions and 25 deletions

View File

@@ -229,20 +229,28 @@ void zmq::session_base_t::clean_pipes ()
void zmq::session_base_t::terminated (pipe_t *pipe_)
{
// Drop the reference to the deallocated pipe.
zmq_assert (pipe == pipe_);
pipe = NULL;
// Drop the reference to the deallocated pipe if required.
zmq_assert (pipe == pipe_ || incomplete_pipes.size () > 0);
// If we are waiting for pending messages to be sent, at this point
// we are sure that there will be no more messages and we can proceed
// with termination safely.
if (pending)
if (pipe == pipe_)
// If this is our current pipe, remove it
pipe = NULL;
else
// Remove the pipe from the detached pipes set
incomplete_pipes.erase (pipe_);
// If we are waiting for pending messages to be sent, at this point
// we are sure that there will be no more messages and we can proceed
// with termination safely.
if (pending && !pipe && incomplete_pipes.size () == 0)
proceed_with_term ();
}
void zmq::session_base_t::read_activated (pipe_t *pipe_)
{
zmq_assert (pipe == pipe_);
// Skip activating if we're detaching this pipe
if (incomplete_pipes.size () > 0 && pipe_ != pipe)
return;
if (likely (engine != NULL))
engine->activate_out ();
@@ -252,7 +260,9 @@ void zmq::session_base_t::read_activated (pipe_t *pipe_)
void zmq::session_base_t::write_activated (pipe_t *pipe_)
{
zmq_assert (pipe == pipe_);
// Skip activating if we're detaching this pipe
if (incomplete_pipes.size () > 0 && pipe_ != pipe)
return;
if (engine)
engine->activate_in ();
@@ -395,6 +405,16 @@ void zmq::session_base_t::detached ()
return;
}
// For delayed connect situations, terminate the pipe
// and reestablish later on
if (pipe && options.delay_attach_on_connect == 1
&& addr->protocol != "pgm" && addr->protocol != "epgm") {
pipe->hiccup ();
pipe->terminate (false);
incomplete_pipes.insert (pipe);
pipe = NULL;
}
reset ();
// Reconnect.