Пример #1
0
static void nn_cws_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_cws *cws;

    cws = nn_cont (self, struct nn_cws, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        if (!nn_sws_isidle (&cws->sws)) {
            nn_ep_stat_increment (cws->ep, NN_STAT_DROPPED_CONNECTIONS, 1);
            nn_sws_stop (&cws->sws);
        }
        cws->state = NN_CWS_STATE_STOPPING_SWS_FINAL;
    }
    if (nn_slow (cws->state == NN_CWS_STATE_STOPPING_SWS_FINAL)) {
        if (!nn_sws_isidle (&cws->sws))
            return;
        nn_backoff_stop (&cws->retry);
        nn_usock_stop (&cws->usock);
        nn_dns_stop (&cws->dns);
        cws->state = NN_CWS_STATE_STOPPING;
    }
    if (nn_slow (cws->state == NN_CWS_STATE_STOPPING)) {
        if (!nn_backoff_isidle (&cws->retry) ||
              !nn_usock_isidle (&cws->usock) ||
              !nn_dns_isidle (&cws->dns))
            return;
        cws->state = NN_CWS_STATE_IDLE;
        nn_fsm_stopped_noevent (&cws->fsm);
        nn_ep_stopped (cws->ep);
        return;
    }

    nn_fsm_bad_state (cws->state, src, type);
}
Пример #2
0
static void nn_ctcp_handler (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_ctcp *ctcp;

    ctcp = nn_cont (self, struct nn_ctcp, fsm);

    switch (ctcp->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/*  The state machine wasn't yet started.                                     */
/******************************************************************************/
    case NN_CTCP_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_ctcp_start_resolving (ctcp);
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  RESOLVING state.                                                          */
/*  Name of the host to connect to is being resolved to get an IP address.    */
/******************************************************************************/
    case NN_CTCP_STATE_RESOLVING:
        switch (src) {

        case NN_CTCP_SRC_DNS:
            switch (type) {
            case NN_DNS_DONE:
                nn_dns_stop (&ctcp->dns);
                ctcp->state = NN_CTCP_STATE_STOPPING_DNS;
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_DNS state.                                                       */
/*  dns object was asked to stop but it haven't stopped yet.                  */
/******************************************************************************/
    case NN_CTCP_STATE_STOPPING_DNS:
        switch (src) {

        case NN_CTCP_SRC_DNS:
            switch (type) {
            case NN_DNS_STOPPED:
                if (ctcp->dns_result.error == 0) {
                    nn_ctcp_start_connecting (ctcp, &ctcp->dns_result.addr,
                        ctcp->dns_result.addrlen);
                    return;
                }
                nn_backoff_start (&ctcp->retry);
                ctcp->state = NN_CTCP_STATE_WAITING;
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  CONNECTING state.                                                         */
/*  Non-blocking connect is under way.                                        */
/******************************************************************************/
    case NN_CTCP_STATE_CONNECTING:
        switch (src) {

        case NN_CTCP_SRC_USOCK:
            switch (type) {
            case NN_USOCK_CONNECTED:
                nn_stcp_start (&ctcp->stcp, &ctcp->usock);
                ctcp->state = NN_CTCP_STATE_ACTIVE;
                nn_epbase_stat_increment (&ctcp->epbase,
                    NN_STAT_INPROGRESS_CONNECTIONS, -1);
                nn_epbase_stat_increment (&ctcp->epbase,
                    NN_STAT_ESTABLISHED_CONNECTIONS, 1);
                nn_epbase_clear_error (&ctcp->epbase);
                return;
            case NN_USOCK_ERROR:
                nn_epbase_set_error (&ctcp->epbase,nn_usock_geterrno(&ctcp->usock),__FILE__,__LINE__);
                nn_usock_stop (&ctcp->usock);
                ctcp->state = NN_CTCP_STATE_STOPPING_USOCK;
                nn_epbase_stat_increment (&ctcp->epbase,
                    NN_STAT_INPROGRESS_CONNECTIONS, -1);
                nn_epbase_stat_increment (&ctcp->epbase,
                    NN_STAT_CONNECT_ERRORS, 1);
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  Connection is established and handled by the stcp state machine.          */
/******************************************************************************/
    case NN_CTCP_STATE_ACTIVE:
        switch (src) {

        case NN_CTCP_SRC_STCP:
            switch (type) {
            case NN_STCP_ERROR:
                nn_stcp_stop (&ctcp->stcp);
                ctcp->state = NN_CTCP_STATE_STOPPING_STCP;
                nn_epbase_stat_increment (&ctcp->epbase,
                    NN_STAT_BROKEN_CONNECTIONS, 1);
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_STCP state.                                                      */
/*  stcp object was asked to stop but it haven't stopped yet.                 */
/******************************************************************************/
    case NN_CTCP_STATE_STOPPING_STCP:
        switch (src) {

        case NN_CTCP_SRC_STCP:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_STCP_STOPPED:
                nn_usock_stop (&ctcp->usock);
                ctcp->state = NN_CTCP_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_USOCK state.                                                     */
/*  usock object was asked to stop but it haven't stopped yet.                */
/******************************************************************************/
    case NN_CTCP_STATE_STOPPING_USOCK:
        switch (src) {

        case NN_CTCP_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_USOCK_STOPPED:
                nn_backoff_start (&ctcp->retry);
                ctcp->state = NN_CTCP_STATE_WAITING;
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  WAITING state.                                                            */
/*  Waiting before re-connection is attempted. This way we won't overload     */
/*  the system by continuous re-connection attemps.                           */
/******************************************************************************/
    case NN_CTCP_STATE_WAITING:
        switch (src) {

        case NN_CTCP_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_TIMEOUT:
                nn_backoff_stop (&ctcp->retry);
                ctcp->state = NN_CTCP_STATE_STOPPING_BACKOFF;
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_BACKOFF state.                                                   */
/*  backoff object was asked to stop, but it haven't stopped yet.             */
/******************************************************************************/
    case NN_CTCP_STATE_STOPPING_BACKOFF:
        switch (src) {

        case NN_CTCP_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_STOPPED:
                nn_ctcp_start_resolving (ctcp);
                return;
            default:
                nn_fsm_bad_action (ctcp->state, src, type);
            }

        default:
            nn_fsm_bad_source (ctcp->state, src, type);
        }

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (ctcp->state, src, type);
    }
}
Пример #3
0
Файл: cws.c Проект: 4ker/nanomsg
static void nn_cws_handler (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_cws *cws;

    cws = nn_cont (self, struct nn_cws, fsm);

    switch (cws->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/*  The state machine wasn't yet started.                                     */
/******************************************************************************/
    case NN_CWS_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_cws_start_resolving (cws);
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  RESOLVING state.                                                          */
/*  Name of the host to connect to is being resolved to get an IP address.    */
/******************************************************************************/
    case NN_CWS_STATE_RESOLVING:
        switch (src) {

        case NN_CWS_SRC_DNS:
            switch (type) {
            case NN_DNS_DONE:
                nn_dns_stop (&cws->dns);
                cws->state = NN_CWS_STATE_STOPPING_DNS;
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_DNS state.                                                       */
/*  dns object was asked to stop but it haven't stopped yet.                  */
/******************************************************************************/
    case NN_CWS_STATE_STOPPING_DNS:
        switch (src) {

        case NN_CWS_SRC_DNS:
            switch (type) {
            case NN_DNS_STOPPED:
                if (cws->dns_result.error == 0) {
                    nn_cws_start_connecting (cws, &cws->dns_result.addr,
                        cws->dns_result.addrlen);
                    return;
                }
                nn_backoff_start (&cws->retry);
                cws->state = NN_CWS_STATE_WAITING;
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  CONNECTING state.                                                         */
/*  Non-blocking connect is under way.                                        */
/******************************************************************************/
    case NN_CWS_STATE_CONNECTING:
        switch (src) {

        case NN_CWS_SRC_USOCK:
            switch (type) {
            case NN_USOCK_CONNECTED:
                nn_sws_start (&cws->sws, &cws->usock, NN_WS_CLIENT,
                    nn_chunkref_data (&cws->resource),
                    nn_chunkref_data (&cws->remote_host), cws->msg_type);
                cws->state = NN_CWS_STATE_ACTIVE;
                cws->peer_gone = 0;
                nn_epbase_stat_increment (&cws->epbase,
                    NN_STAT_INPROGRESS_CONNECTIONS, -1);
                nn_epbase_stat_increment (&cws->epbase,
                    NN_STAT_ESTABLISHED_CONNECTIONS, 1);
                nn_epbase_clear_error (&cws->epbase);
                return;
            case NN_USOCK_ERROR:
                nn_epbase_set_error (&cws->epbase,
                    nn_usock_geterrno (&cws->usock));
                nn_usock_stop (&cws->usock);
                cws->state = NN_CWS_STATE_STOPPING_USOCK;
                nn_epbase_stat_increment (&cws->epbase,
                    NN_STAT_INPROGRESS_CONNECTIONS, -1);
                nn_epbase_stat_increment (&cws->epbase,
                    NN_STAT_CONNECT_ERRORS, 1);
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  Connection is established and handled by the sws state machine.           */
/******************************************************************************/
    case NN_CWS_STATE_ACTIVE:
        switch (src) {

        case NN_CWS_SRC_SWS:
            switch (type) {
            case NN_SWS_RETURN_CLOSE_HANDSHAKE:
                /*  Peer closed connection without intention to reconnect, or
                    local endpoint failed remote because of invalid data. */
                nn_sws_stop (&cws->sws);
                cws->state = NN_CWS_STATE_STOPPING_SWS;
                cws->peer_gone = 1;
                return;
            case NN_SWS_RETURN_ERROR:
                nn_sws_stop (&cws->sws);
                cws->state = NN_CWS_STATE_STOPPING_SWS;
                nn_epbase_stat_increment (&cws->epbase,
                    NN_STAT_BROKEN_CONNECTIONS, 1);
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_SWS state.                                                       */
/*  sws object was asked to stop but it haven't stopped yet.                  */
/******************************************************************************/
    case NN_CWS_STATE_STOPPING_SWS:
        switch (src) {

        case NN_CWS_SRC_SWS:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_SWS_RETURN_STOPPED:
                nn_usock_stop (&cws->usock);
                cws->state = NN_CWS_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_USOCK state.                                                     */
/*  usock object was asked to stop but it haven't stopped yet.                */
/******************************************************************************/
    case NN_CWS_STATE_STOPPING_USOCK:
        switch (src) {

        case NN_CWS_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_USOCK_STOPPED:
                /*  If the peer has confirmed itself gone with a Closing
                    Handshake, or if the local endpoint failed the remote,
                    don't try to reconnect. */
                if (!cws->peer_gone) {
                    nn_backoff_start (&cws->retry);
                    cws->state = NN_CWS_STATE_WAITING;
                }
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  WAITING state.                                                            */
/*  Waiting before re-connection is attempted. This way we won't overload     */
/*  the system by continuous re-connection attemps.                           */
/******************************************************************************/
    case NN_CWS_STATE_WAITING:
        switch (src) {

        case NN_CWS_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_TIMEOUT:
                nn_backoff_stop (&cws->retry);
                cws->state = NN_CWS_STATE_STOPPING_BACKOFF;
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_BACKOFF state.                                                   */
/*  backoff object was asked to stop, but it haven't stopped yet.             */
/******************************************************************************/
    case NN_CWS_STATE_STOPPING_BACKOFF:
        switch (src) {

        case NN_CWS_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_STOPPED:
                nn_cws_start_resolving (cws);
                return;
            default:
                nn_fsm_bad_action (cws->state, src, type);
            }

        default:
            nn_fsm_bad_source (cws->state, src, type);
        }

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (cws->state, src, type);
    }
}