コード例 #1
0
ファイル: btcp.c プロジェクト: zakharov/nanomsg
static void nn_btcp_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_btcp *btcp;
    struct nn_list_item *it;
    struct nn_atcp *atcp;

    btcp = nn_cont (self, struct nn_btcp, fsm);
    nn_assert (btcp);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_backoff_stop (&btcp->retry);
        if (btcp->atcp) {
            nn_atcp_stop (btcp->atcp);
            btcp->state = NN_BTCP_STATE_STOPPING_ATCP;
        }
        else {
            btcp->state = NN_BTCP_STATE_STOPPING_USOCK;
        }
    }
    if (nn_slow (btcp->state == NN_BTCP_STATE_STOPPING_ATCP)) {
        if (!nn_atcp_isidle (btcp->atcp))
            return;
        nn_atcp_term (btcp->atcp);
        nn_free (btcp->atcp);
        btcp->atcp = NULL;
        nn_usock_stop (&btcp->usock);
        btcp->state = NN_BTCP_STATE_STOPPING_USOCK;
    }
    if (nn_slow (btcp->state == NN_BTCP_STATE_STOPPING_USOCK)) {
       if (!nn_usock_isidle (&btcp->usock))
            return;
        for (it = nn_list_begin (&btcp->atcps);
              it != nn_list_end (&btcp->atcps);
              it = nn_list_next (&btcp->atcps, it)) {
            atcp = nn_cont (it, struct nn_atcp, item);
            nn_atcp_stop (atcp);
        }
        btcp->state = NN_BTCP_STATE_STOPPING_ATCPS;
        goto atcps_stopping;
    }
    if (nn_slow (btcp->state == NN_BTCP_STATE_STOPPING_ATCPS)) {
        nn_assert (src == NN_BTCP_SRC_ATCP && type == NN_ATCP_STOPPED);
        atcp = (struct nn_atcp *) srcptr;
        nn_list_erase (&btcp->atcps, &atcp->item);
        nn_atcp_term (atcp);
        nn_free (atcp);

        /*  If there are no more atcp state machines, we can stop the whole
            btcp object. */
atcps_stopping:
        if (nn_list_empty (&btcp->atcps)) {
            btcp->state = NN_BTCP_STATE_IDLE;
            nn_fsm_stopped_noevent (&btcp->fsm);
            nn_epbase_stopped (&btcp->epbase);
            return;
        }

        return;
    }

    nn_fsm_bad_action(btcp->state, src, type);
}
コード例 #2
0
ファイル: btcp.c プロジェクト: JadeHub/nanomsg
static void nn_btcp_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_btcp *btcp;
    struct nn_list_item *it;
    struct nn_atcp *atcp;

    btcp = nn_cont (self, struct nn_btcp, fsm);

/******************************************************************************/
/*  STOP procedure.                                                           */
/******************************************************************************/
    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_atcp_stop (btcp->atcp);
        btcp->state = NN_BTCP_STATE_STOPPING_ATCP;
    }
    if (nn_slow (btcp->state == NN_BTCP_STATE_STOPPING_ATCP)) {
        if (!nn_atcp_isidle (btcp->atcp))
            return;
        nn_atcp_term (btcp->atcp);
        nn_free (btcp->atcp);
        btcp->atcp = NULL;
        nn_usock_stop (&btcp->usock);
        btcp->state = NN_BTCP_STATE_STOPPING_USOCK;
    }
    if (nn_slow (btcp->state == NN_BTCP_STATE_STOPPING_USOCK)) {
       if (!nn_usock_isidle (&btcp->usock))
            return;
        for (it = nn_list_begin (&btcp->atcps);
              it != nn_list_end (&btcp->atcps);
              it = nn_list_next (&btcp->atcps, it)) {
            atcp = nn_cont (it, struct nn_atcp, item);
            nn_atcp_stop (atcp);
        }
        btcp->state = NN_BTCP_STATE_STOPPING_ATCPS;
        goto atcps_stopping;
    }
    if (nn_slow (btcp->state == NN_BTCP_STATE_STOPPING_ATCPS)) {
        nn_assert (src == NN_BTCP_SRC_ATCP && type == NN_ATCP_STOPPED);
        atcp = (struct nn_atcp *) srcptr;
        nn_list_erase (&btcp->atcps, &atcp->item);
        nn_atcp_term (atcp);
        nn_free (atcp);

        /*  If there are no more atcp state machines, we can stop the whole
            btcp object. */
atcps_stopping:
        if (nn_list_empty (&btcp->atcps)) {
            btcp->state = NN_BTCP_STATE_IDLE;
            nn_fsm_stopped_noevent (&btcp->fsm);
            nn_epbase_stopped (&btcp->epbase);
            return;
        }

        return;
    }

    switch (btcp->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/******************************************************************************/
    case NN_BTCP_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_btcp_start_listening (btcp);
                nn_btcp_start_accepting (btcp);
                btcp->state = NN_BTCP_STATE_ACTIVE;
                return;
            default:
                nn_fsm_bad_action (btcp->state, src, type);
            }

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

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  The execution is yielded to the atcp state machine in this state.         */
/******************************************************************************/
    case NN_BTCP_STATE_ACTIVE:
        if (srcptr == btcp->atcp) {
            switch (type) {
            case NN_ATCP_ACCEPTED:

                /*  Move the newly created connection to the list of existing
                    connections. */
                nn_list_insert (&btcp->atcps, &btcp->atcp->item,
                    nn_list_end (&btcp->atcps));
                btcp->atcp = NULL;

                /*  Start waiting for a new incoming connection. */
                nn_btcp_start_accepting (btcp);

                return;

            default:
                nn_fsm_bad_action (btcp->state, src, type);
            }
        }

        /*  For all remaining events we'll assume they are coming from one
            of remaining child atcp objects. */
        nn_assert (src == NN_BTCP_SRC_ATCP);
        atcp = (struct nn_atcp*) srcptr;
        switch (type) {
        case NN_ATCP_ERROR:
            nn_atcp_stop (atcp);
            return;
        case NN_ATCP_STOPPED:
            nn_list_erase (&btcp->atcps, &atcp->item);
            nn_atcp_term (atcp);
            nn_free (atcp);
            return;
        default:
            nn_fsm_bad_action (btcp->state, src, type);
        }

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