示例#1
0
文件: pipe.cpp 项目: steve-o/libzmq
void zmq::pipe_t::process_pipe_term_ack ()
{
    //  Notify the user that all the references to the pipe should be dropped.
    zmq_assert (sink);
    sink->pipe_terminated (this);

    //  In term_ack_sent and term_req_sent2 states there's nothing to do.
    //  Simply deallocate the pipe. In term_req_sent1 state we have to ack
    //  the peer before deallocating this side of the pipe.
    //  All the other states are invalid.
    if (state == term_req_sent1) {
        outpipe = NULL;
        send_pipe_term_ack (peer);
    }
    else
        zmq_assert (state == term_ack_sent || state == term_req_sent2);

    //  We'll deallocate the inbound pipe, the peer will deallocate the outbound
    //  pipe (which is an inbound pipe from its point of view).
    //  First, delete all the unread messages in the pipe. We have to do it by
    //  hand because msg_t doesn't have automatic destructor. Then deallocate
    //  the ypipe itself.
    msg_t msg;
    while (inpipe->read (&msg)) {
        int rc = msg.close ();
        errno_assert (rc == 0);
    }
    delete inpipe;

    //  Deallocate the pipe object
    delete this;
}
示例#2
0
文件: pipe.cpp 项目: AmesianX/libzmq
void zmq::pipe_t::terminate (bool delay_)
{
    //  Overload the value specified at pipe creation.
    delay = delay_;

    //  If terminate was already called, we can ignore the duplicate invocation.
    if (state == term_req_sent1 || state == term_req_sent2) {
        return;
    }
    //  If the pipe is in the final phase of async termination, it's going to
    //  closed anyway. No need to do anything special here.
    else if (state == term_ack_sent) {
        return;
    }
    //  The simple sync termination case. Ask the peer to terminate and wait
    //  for the ack.
    else if (state == active) {
        send_pipe_term (peer);
        state = term_req_sent1;
    }
    //  There are still pending messages available, but the user calls
    //  'terminate'. We can act as if all the pending messages were read.
    else if (state == waiting_for_delimiter && !delay) {
        //  Drop any unfinished outbound messages.
        rollback ();
        outpipe = NULL;
        send_pipe_term_ack (peer);
        state = term_ack_sent;
    }
    //  If there are pending messages still available, do nothing.
    else if (state == waiting_for_delimiter) {
    }
    //  We've already got delimiter, but not term command yet. We can ignore
    //  the delimiter and ack synchronously terminate as if we were in
    //  active state.
    else if (state == delimiter_received) {
        send_pipe_term (peer);
        state = term_req_sent1;
    }
    //  There are no other states.
    else {
        zmq_assert (false);
    }

    //  Stop outbound flow of messages.
    out_active = false;

    if (outpipe) {

        //  Drop any unfinished outbound messages.
        rollback ();

        //  Write the delimiter into the pipe. Note that watermarks are not
        //  checked; thus the delimiter can be written even when the pipe is full.
        msg_t msg;
        msg.init_delimiter ();
        outpipe->write (msg, false);
        flush ();
    }
}
示例#3
0
void zmq::writer_t::process_pipe_term ()
{
    if (endpoint)
        endpoint->detach_outpipe (this);

    reader_t *p = peer;
    peer = NULL;
    send_pipe_term_ack (p);
}
示例#4
0
文件: pipe.cpp 项目: adeze/libxs
void xs::pipe_t::process_pipe_term ()
{
    //  This is the simple case of peer-induced termination. If there are no
    //  more pending messages to read, or if the pipe was configured to drop
    //  pending messages, we can move directly to the terminating state.
    //  Otherwise we'll hang up in pending state till all the pending messages
    //  are sent.
    if (state == active) {
        if (!delay) {
            state = terminating;
            outpipe = NULL;
            send_pipe_term_ack (peer);
            return;
        }
        else {
            state = pending;
            return;
        }
    }

    //  Delimiter happened to arrive before the term command. Now we have the
    //  term command as well, so we can move straight to terminating state.
    if (state == delimited) {
        state = terminating;
        outpipe = NULL;
        send_pipe_term_ack (peer);
        return;
    }

    //  This is the case where both ends of the pipe are closed in parallel.
    //  We simply reply to the request by ack and continue waiting for our
    //  own ack.
    if (state == terminated) {
        state = double_terminated;
        outpipe = NULL;
        send_pipe_term_ack (peer);
        return;
    }

    //  pipe_term is invalid in other states.
    xs_assert (false);
}
示例#5
0
文件: pipe.cpp 项目: somdoron/libzmq
void zmq::pipe_t::process_delimiter ()
{
    zmq_assert (_state == active || _state == waiting_for_delimiter);

    if (_state == active)
        _state = delimiter_received;
    else {
        _out_pipe = NULL;
        send_pipe_term_ack (_peer);
        _state = term_ack_sent;
    }
}
示例#6
0
void zmq::pipe_t::process_pipe_term ()
{
    zmq_assert (state == active
            ||  state == delimiter_received
            ||  state == term_req_sent1);

    //  This is the simple case of peer-induced termination. If there are no
    //  more pending messages to read, or if the pipe was configured to drop
    //  pending messages, we can move directly to the term_ack_sent state.
    //  Otherwise we'll hang up in waiting_for_delimiter state till all
    //  pending messages are read.
    if (state == active) {
        if (delay)
            state = waiting_for_delimiter;
        else {
            state = term_ack_sent;
            outpipe = NULL;
            send_pipe_term_ack (peer);
        }
    }

    //  Delimiter happened to arrive before the term command. Now we have the
    //  term command as well, so we can move straight to term_ack_sent state.
    else
    if (state == delimiter_received) {
        state = term_ack_sent;
        outpipe = NULL;
        send_pipe_term_ack (peer);
    }

    //  This is the case where both ends of the pipe are closed in parallel.
    //  We simply reply to the request by ack and continue waiting for our
    //  own ack.
    else
    if (state == term_req_sent1) {
        state = term_req_sent2;
        outpipe = NULL;
        send_pipe_term_ack (peer);
    }
}
示例#7
0
文件: pipe.cpp 项目: steve-o/libzmq
void zmq::pipe_t::process_delimiter ()
{
    zmq_assert (state == active
                ||  state == waiting_for_delimiter);

    if (state == active)
        state = delimiter_received;
    else {
        outpipe = NULL;
        send_pipe_term_ack (peer);
        state = term_ack_sent;
    }
}
示例#8
0
文件: pipe.cpp 项目: scastillo/libzmq
void zmq::writer_t::process_pipe_term ()
{
    send_pipe_term_ack (reader);

    //  The above command allows reader to deallocate itself and the pipe.
    //  For safety's sake we'll drop the pointers here.
    reader = NULL;
    pipe = NULL;

    //  Notify owner about the termination.
    zmq_assert (sink);
    sink->terminated (this);

    //  Deallocate the resources.
    delete this;
}
示例#9
0
文件: pipe.cpp 项目: adeze/libxs
void xs::pipe_t::delimit ()
{
    if (state == active) {
        state = delimited;
        return;
    }

    if (state == pending) {
        outpipe = NULL;
        send_pipe_term_ack (peer);
        state = terminating;
        return;
    }

    //  Delimiter in any other state is invalid.
    xs_assert (false);
}