Exemplo n.º 1
0
static void nn_cipc_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_cipc *cipc;

    cipc = nn_cont (self, struct nn_cipc, fsm);

/******************************************************************************/
/*  STOP procedure.                                                           */
/******************************************************************************/
    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_sipc_stop (&cipc->sipc);
        cipc->state = NN_CIPC_STATE_STOPPING_SIPC_FINAL;
    }
    if (nn_slow (cipc->state == NN_CIPC_STATE_STOPPING_SIPC_FINAL)) {
        if (!nn_sipc_isidle (&cipc->sipc))
            return;
        nn_backoff_stop (&cipc->retry);
        nn_usock_stop (&cipc->usock);
        cipc->state = NN_CIPC_STATE_STOPPING;
    }
    if (nn_slow (cipc->state == NN_CIPC_STATE_STOPPING)) {
        if (!nn_backoff_isidle (&cipc->retry) ||
              !nn_usock_isidle (&cipc->usock))
            return;
        cipc->state = NN_CIPC_STATE_IDLE;
        nn_fsm_stopped_noevent (&cipc->fsm);
        nn_epbase_stopped (&cipc->epbase);
        return;
    }

    switch (cipc->state) {

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

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

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

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

        case NN_CIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_CONNECTED:
                nn_sipc_start (&cipc->sipc, &cipc->usock);
                cipc->state = NN_CIPC_STATE_ACTIVE;
                return;
            case NN_USOCK_ERROR:
                nn_usock_stop (&cipc->usock);
                cipc->state = NN_CIPC_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

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

        case NN_CIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_ERROR:
                nn_sipc_stop (&cipc->sipc);
                cipc->state = NN_CIPC_STATE_STOPPING_SIPC;
                return;
            default:
               nn_fsm_bad_action (cipc->state, src, type);
            }

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

/******************************************************************************/
/*  STOPPING_SIPC state.                                                      */
/*  sipc object was asked to stop but it haven't stopped yet.                 */
/******************************************************************************/
    case NN_CIPC_STATE_STOPPING_SIPC:
        switch (src) {

        case NN_CIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_STOPPED:
                nn_usock_stop (&cipc->usock);
                cipc->state = NN_CIPC_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

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

        case NN_CIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_STOPPED:
                nn_backoff_start (&cipc->retry);
                cipc->state = NN_CIPC_STATE_WAITING;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

        default:
            nn_fsm_bad_source (cipc->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_CIPC_STATE_WAITING:
        switch (src) {

        case NN_CIPC_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_TIMEOUT:
                nn_backoff_stop (&cipc->retry);
                cipc->state = NN_CIPC_STATE_STOPPING_BACKOFF;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

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

        case NN_CIPC_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_STOPPED:
                nn_cipc_start_connecting (cipc);
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (cipc->state, src, type);
    }
}
Exemplo n.º 2
0
static void nn_aipc_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_aipc *aipc;

    aipc = nn_cont (self, struct nn_aipc, fsm);

/******************************************************************************/
/*  STOP procedure.                                                           */
/******************************************************************************/
    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_sipc_stop (&aipc->sipc);
        aipc->state = NN_AIPC_STATE_STOPPING_SIPC_FINAL;
    }
    if (nn_slow (aipc->state == NN_AIPC_STATE_STOPPING_SIPC_FINAL)) {
        if (!nn_sipc_isidle (&aipc->sipc))
            return;
        nn_usock_stop (&aipc->usock);
        aipc->state = NN_AIPC_STATE_STOPPING;
    }
    if (nn_slow (aipc->state == NN_AIPC_STATE_STOPPING)) {
        if (!nn_usock_isidle (&aipc->usock))
            return;
       if (aipc->listener) {
            nn_assert (aipc->listener_owner.fsm);
            nn_usock_swap_owner (aipc->listener, &aipc->listener_owner);
            aipc->listener = NULL;
            aipc->listener_owner.src = 1;
            aipc->listener_owner.fsm = NULL;
        }
        aipc->state = NN_AIPC_STATE_IDLE;
        nn_fsm_stopped (&aipc->fsm, NN_AIPC_STOPPED);
        return;
    }

    switch (aipc->state) {

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

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_usock_accept (&aipc->usock, aipc->listener);
                aipc->state = NN_AIPC_STATE_ACCEPTING;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  ACCEPTING state.                                                          */
/*  Waiting for incoming connection.                                          */
/******************************************************************************/
    case NN_AIPC_STATE_ACCEPTING:
        switch (src) {

        case NN_AIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_ACCEPTED:

                /*  Return ownership of the listening socket to the parent. */
                nn_usock_swap_owner (aipc->listener, &aipc->listener_owner);
                aipc->listener = NULL;
                aipc->listener_owner.src = -1;
                aipc->listener_owner.fsm = NULL;
                nn_fsm_raise (&aipc->fsm, &aipc->accepted, NN_AIPC_ACCEPTED);

                /*  Start the sipc state machine. */
                nn_usock_activate (&aipc->usock);
                nn_sipc_start (&aipc->sipc, &aipc->usock);
                aipc->state = NN_AIPC_STATE_ACTIVE;

                return;

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

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

/******************************************************************************/
/*  ACTIVE state.                                                             */
/******************************************************************************/
    case NN_AIPC_STATE_ACTIVE:
        switch (src) {

        case NN_AIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_ERROR:
                nn_sipc_stop (&aipc->sipc);
                aipc->state = NN_AIPC_STATE_STOPPING_SIPC;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  STOPPING_SIPC state.                                                      */
/******************************************************************************/
    case NN_AIPC_STATE_STOPPING_SIPC:
        switch (src) {

        case NN_AIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_STOPPED:
                nn_usock_stop (&aipc->usock);
                aipc->state = NN_AIPC_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  STOPPING_USOCK state.                                                      */
/******************************************************************************/
    case NN_AIPC_STATE_STOPPING_USOCK:
        switch (src) {

        case NN_AIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_STOPPED:
                nn_fsm_raise (&aipc->fsm, &aipc->done, NN_AIPC_ERROR);
                aipc->state = NN_AIPC_STATE_DONE;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (aipc->state, src, type);
    }
}
Exemplo n.º 3
0
static void nn_cipc_handler (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_cipc *cipc;

    cipc = nn_cont (self, struct nn_cipc, fsm);

    switch (cipc->state) {

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

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

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

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

        case NN_CIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_CONNECTED:
                nn_sipc_start (&cipc->sipc, &cipc->usock);
                cipc->state = NN_CIPC_STATE_ACTIVE;
                nn_epbase_stat_increment (&cipc->epbase,
                    NN_STAT_INPROGRESS_CONNECTIONS, -1);
                nn_epbase_stat_increment (&cipc->epbase,
                    NN_STAT_ESTABLISHED_CONNECTIONS, 1);
                nn_epbase_clear_error (&cipc->epbase);
                return;
            case NN_USOCK_ERROR:
                nn_epbase_set_error (&cipc->epbase,nn_usock_geterrno (&cipc->usock),__FILE__,__LINE__);
                nn_usock_stop (&cipc->usock);
                cipc->state = NN_CIPC_STATE_STOPPING_USOCK;
                nn_epbase_stat_increment (&cipc->epbase,
                    NN_STAT_INPROGRESS_CONNECTIONS, -1);
                nn_epbase_stat_increment (&cipc->epbase,
                    NN_STAT_CONNECT_ERRORS, 1);
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

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

        case NN_CIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_ERROR:
                nn_sipc_stop (&cipc->sipc);
                cipc->state = NN_CIPC_STATE_STOPPING_SIPC;
                nn_epbase_stat_increment (&cipc->epbase,
                    NN_STAT_BROKEN_CONNECTIONS, 1);
                return;
            default:
               nn_fsm_bad_action (cipc->state, src, type);
            }

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

/******************************************************************************/
/*  STOPPING_SIPC state.                                                      */
/*  sipc object was asked to stop but it haven't stopped yet.                 */
/******************************************************************************/
    case NN_CIPC_STATE_STOPPING_SIPC:
        switch (src) {

        case NN_CIPC_SRC_SIPC:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_SIPC_STOPPED:
                nn_usock_stop (&cipc->usock);
                cipc->state = NN_CIPC_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

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

        case NN_CIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_USOCK_STOPPED:
                nn_backoff_start (&cipc->retry);
                cipc->state = NN_CIPC_STATE_WAITING;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

        default:
            nn_fsm_bad_source (cipc->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_CIPC_STATE_WAITING:
        switch (src) {

        case NN_CIPC_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_TIMEOUT:
                nn_backoff_stop (&cipc->retry);
                cipc->state = NN_CIPC_STATE_STOPPING_BACKOFF;
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

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

        case NN_CIPC_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_STOPPED:
                nn_cipc_start_connecting (cipc);
                return;
            default:
                nn_fsm_bad_action (cipc->state, src, type);
            }

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

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (cipc->state, src, type);
    }
}
Exemplo n.º 4
0
Arquivo: aipc.c Projeto: antmd/nanomsg
static void nn_aipc_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_aipc *aipc;
    int val;
    size_t sz;

    aipc = nn_cont (self, struct nn_aipc, fsm);

    switch (aipc->state) {

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

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_usock_accept (&aipc->usock, aipc->listener);
                aipc->state = NN_AIPC_STATE_ACCEPTING;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  ACCEPTING state.                                                          */
/*  Waiting for incoming connection.                                          */
/******************************************************************************/
    case NN_AIPC_STATE_ACCEPTING:
        switch (src) {

        case NN_AIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_ACCEPTED:

                /*  Set the relevant socket options. */
                sz = sizeof (val);
                nn_epbase_getopt (aipc->epbase, NN_SOL_SOCKET, NN_SNDBUF,
                    &val, &sz);
                nn_assert (sz == sizeof (val));
                nn_usock_setsockopt (&aipc->usock, SOL_SOCKET, SO_SNDBUF,
                    &val, sizeof (val));
                sz = sizeof (val);
                nn_epbase_getopt (aipc->epbase, NN_SOL_SOCKET, NN_RCVBUF,
                    &val, &sz);
                nn_assert (sz == sizeof (val));
                nn_usock_setsockopt (&aipc->usock, SOL_SOCKET, SO_RCVBUF,
                    &val, sizeof (val));

                /*  Return ownership of the listening socket to the parent. */
                nn_usock_swap_owner (aipc->listener, &aipc->listener_owner);
                aipc->listener = NULL;
                aipc->listener_owner.src = -1;
                aipc->listener_owner.fsm = NULL;
                nn_fsm_raise (&aipc->fsm, &aipc->accepted, NN_AIPC_ACCEPTED);

                /*  Start the sipc state machine. */
                nn_usock_activate (&aipc->usock);
                nn_sipc_start (&aipc->sipc, &aipc->usock);
                aipc->state = NN_AIPC_STATE_ACTIVE;

                return;

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

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

/******************************************************************************/
/*  ACTIVE state.                                                             */
/******************************************************************************/
    case NN_AIPC_STATE_ACTIVE:
        switch (src) {

        case NN_AIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_ERROR:
                nn_sipc_stop (&aipc->sipc);
                aipc->state = NN_AIPC_STATE_STOPPING_SIPC;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  STOPPING_SIPC state.                                                      */
/******************************************************************************/
    case NN_AIPC_STATE_STOPPING_SIPC:
        switch (src) {

        case NN_AIPC_SRC_SIPC:
            switch (type) {
            case NN_SIPC_STOPPED:
                nn_usock_stop (&aipc->usock);
                aipc->state = NN_AIPC_STATE_STOPPING_USOCK;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

/******************************************************************************/
/*  STOPPING_USOCK state.                                                      */
/******************************************************************************/
    case NN_AIPC_STATE_STOPPING_USOCK:
        switch (src) {

        case NN_AIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_STOPPED:
                nn_fsm_raise (&aipc->fsm, &aipc->done, NN_AIPC_ERROR);
                aipc->state = NN_AIPC_STATE_DONE;
                return;
            default:
                nn_fsm_bad_action (aipc->state, src, type);
            }

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

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