Exemple #1
0
static void nn_cinproc_shutdown (struct nn_fsm *self, int src, int type,
                                 NN_UNUSED void *srcptr)
{
    struct nn_cinproc *cinproc;

    cinproc = nn_cont (self, struct nn_cinproc, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {

        /*  First, unregister the endpoint from the global repository of inproc
            endpoints. This way, new connections cannot be created anymore. */
        nn_ins_disconnect (&cinproc->item);

        /*  Stop the existing connection. */
        nn_sinproc_stop (&cinproc->sinproc);
        cinproc->state = NN_CINPROC_STATE_STOPPING;
    }
    if (nn_slow (cinproc->state == NN_CINPROC_STATE_STOPPING)) {
        if (!nn_sinproc_isidle (&cinproc->sinproc))
            return;
        cinproc->state = NN_CINPROC_STATE_IDLE;
        nn_fsm_stopped_noevent (&cinproc->fsm);
        nn_epbase_stopped (&cinproc->item.epbase);
        return;
    }

    nn_fsm_bad_state(cinproc->state, src, type);
}
Exemple #2
0
static void nn_cipc_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_cipc *cipc;

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

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        if (!nn_sipc_isidle (&cipc->sipc)) {
            nn_epbase_stat_increment (&cipc->epbase,
                NN_STAT_DROPPED_CONNECTIONS, 1);
            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;
    }

    nn_fsm_bad_state(cipc->state, src, type);
}
Exemple #3
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);
}
Exemple #4
0
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);

    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;
    }

    nn_fsm_bad_action(btcp->state, src, type);
}
Exemple #5
0
static void nn_bipc_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_bipc *bipc;
    struct nn_list_item *it;
    struct nn_aipc *aipc;

    bipc = nn_cont (self, struct nn_bipc, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_aipc_stop (bipc->aipc);
        bipc->state = NN_BIPC_STATE_STOPPING_AIPC;
    }
    if (nn_slow (bipc->state == NN_BIPC_STATE_STOPPING_AIPC)) {
        if (!nn_aipc_isidle (bipc->aipc))
            return;
        nn_aipc_term (bipc->aipc);
        nn_free (bipc->aipc);
        bipc->aipc = NULL;
        nn_usock_stop (&bipc->usock);
        bipc->state = NN_BIPC_STATE_STOPPING_USOCK;
    }
    if (nn_slow (bipc->state == NN_BIPC_STATE_STOPPING_USOCK)) {
       if (!nn_usock_isidle (&bipc->usock))
            return;
        for (it = nn_list_begin (&bipc->aipcs);
              it != nn_list_end (&bipc->aipcs);
              it = nn_list_next (&bipc->aipcs, it)) {
            aipc = nn_cont (it, struct nn_aipc, item);
            nn_aipc_stop (aipc);
        }
        bipc->state = NN_BIPC_STATE_STOPPING_AIPCS;
        goto aipcs_stopping;
    }
    if (nn_slow (bipc->state == NN_BIPC_STATE_STOPPING_AIPCS)) {
        nn_assert (src == NN_BIPC_SRC_AIPC && type == NN_AIPC_STOPPED);
        aipc = (struct nn_aipc *) srcptr;
        nn_list_erase (&bipc->aipcs, &aipc->item);
        nn_aipc_term (aipc);
        nn_free (aipc);

        /*  If there are no more aipc state machines, we can stop the whole
            bipc object. */
aipcs_stopping:
        if (nn_list_empty (&bipc->aipcs)) {
            bipc->state = NN_BIPC_STATE_IDLE;
            nn_fsm_stopped_noevent (&bipc->fsm);
            nn_epbase_stopped (&bipc->epbase);
            return;
        }

        return;
    }

    nn_fsm_bad_state(bipc->state, src, type);
}
Exemple #6
0
int nn_sock_term (struct nn_sock *self)
{
    int rc;
    int i;

    /*  NOTE: nn_sock_stop must have already been called. */

    /*  Some endpoints may still be alive.  Here we are going to wait
        till they are all closed.  This loop is not interruptible, because
        making it so would leave a partially cleaned up socket, and we don't
        have a way to defer resource deallocation. */
    for (;;) {
        rc = nn_sem_wait (&self->termsem);
        if (nn_slow (rc == -EINTR))
            continue;
        errnum_assert (rc == 0, -rc);
        break;
    }

    /*  Also, wait for all holds on the socket to be released.  */
    for (;;) {
        rc = nn_sem_wait (&self->relesem);
        if (nn_slow (rc == -EINTR))
            continue;
        errnum_assert (rc == 0, -rc);
        break;
    }

    /*  Threads that posted the semaphore(s) can still have the ctx locked
        for a short while. By simply entering the context and exiting it
        immediately we can be sure that any such threads have already
        exited the context. */
    nn_ctx_enter (&self->ctx);
    nn_ctx_leave (&self->ctx);

    /*  At this point, we can be reasonably certain that no other thread
        has any references to the socket. */

    nn_fsm_stopped_noevent (&self->fsm);
    nn_fsm_term (&self->fsm);
    nn_sem_term (&self->termsem);
    nn_list_term (&self->sdeps);
    nn_list_term (&self->eps);
    nn_clock_term (&self->clock);
    nn_ctx_term (&self->ctx);

    /*  Destroy any optsets associated with the socket. */
    for (i = 0; i != NN_MAX_TRANSPORT; ++i)
        if (self->optsets [i])
            self->optsets [i]->vfptr->destroy (self->optsets [i]);

    return 0;
}
Exemple #7
0
int nn_sock_term (struct nn_sock *self)
{
    int rc;
    int i;

    /*  Ask the state machine to start closing the socket. */
    nn_ctx_enter (&self->ctx);
    nn_fsm_stop (&self->fsm);
    nn_ctx_leave (&self->ctx);

    /*  Shutdown process was already started but some endpoints may still
        alive. Here we are going to wait till they are all closed. */
    rc = nn_sem_wait (&self->termsem);
    if (nn_slow (rc == -EINTR))
        return -EINTR;
    errnum_assert (rc == 0, -rc);

    /*  The thread that posted the semaphore can still have the ctx locked
        for a short while. By simply entering the context and exiting it
        immediately we can be sure that the thread in question have already
        exited the context. */
    nn_ctx_enter (&self->ctx);
    nn_ctx_leave (&self->ctx);

    /*  Deallocate the resources. */
    nn_fsm_stopped_noevent (&self->fsm);
    nn_fsm_term (&self->fsm);
    nn_sem_term (&self->termsem);
    nn_list_term (&self->sdeps);
    nn_list_term (&self->eps);
    nn_clock_term (&self->clock);
    nn_ctx_term (&self->ctx);

    /*  Destroy any optsets associated with the socket. */
    for (i = 0; i != NN_MAX_TRANSPORT; ++i)
        if (self->optsets [i])
            self->optsets [i]->vfptr->destroy (self->optsets [i]);

    return 0;
}
Exemple #8
0
static void nn_surveyor_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_surveyor *surveyor;

    surveyor = nn_cont (self, struct nn_surveyor, fsm);

    if (nn_slow (src== NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_timer_stop (&surveyor->timer);
        surveyor->state = NN_SURVEYOR_STATE_STOPPING;
    }
    if (nn_slow (surveyor->state == NN_SURVEYOR_STATE_STOPPING)) {
        if (!nn_timer_isidle (&surveyor->timer))
            return;
        surveyor->state = NN_SURVEYOR_STATE_IDLE;
        nn_fsm_stopped_noevent (&surveyor->fsm);
        nn_sockbase_stopped (&surveyor->xsurveyor.sockbase);
        return;
    }

    nn_fsm_bad_state(surveyor->state, src, type);
}
Exemple #9
0
void nn_req_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_req *req;

    req = nn_cont (self, struct nn_req, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_timer_stop (&req->task.timer);
        req->state = NN_REQ_STATE_STOPPING;
    }
    if (nn_slow (req->state == NN_REQ_STATE_STOPPING)) {
        if (!nn_timer_isidle (&req->task.timer))
            return;
        req->state = NN_REQ_STATE_IDLE;
        nn_fsm_stopped_noevent (&req->fsm);
        nn_sockbase_stopped (&req->xreq.sockbase);
        return;
    }

    nn_fsm_bad_state(req->state, src, type);
}
Exemple #10
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);
    }
}
Exemple #11
0
static void nn_req_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_req *req;

    req = nn_cont (self, struct nn_req, fsm);

/******************************************************************************/
/*  STOP procedure.                                                           */
/******************************************************************************/
    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_timer_stop (&req->timer);
        req->state = NN_REQ_STATE_STOPPING;
    }
    if (nn_slow (req->state == NN_REQ_STATE_STOPPING)) {
        if (!nn_timer_isidle (&req->timer))
            return;
        req->state = NN_REQ_STATE_IDLE;
        nn_fsm_stopped_noevent (&req->fsm);
        nn_sockbase_stopped (&req->xreq.sockbase);
        return;
    }

    switch (req->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/*  The socket was created recently. Intermediate state.                      */
/*  Pass straight to the PASSIVE state.                                       */
/******************************************************************************/
    case NN_REQ_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                req->state = NN_REQ_STATE_PASSIVE;
                return;
            default:
                nn_assert (0);
            }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  PASSIVE state.                                                            */
/*  No request is submitted.                                                  */
/******************************************************************************/
    case NN_REQ_STATE_PASSIVE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_REQ_ACTION_SENT:
                nn_req_action_send (req);
                return;
            default:
                nn_assert (0);
            }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  DELAYED state.                                                            */
/*  Request was submitted but it could not be sent to the network because     */
/*  there was no peer available at the moment. Now we are waiting for the     */
/*  peer to arrive to send the request to it.                                 */
/******************************************************************************/
    case NN_REQ_STATE_DELAYED:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_REQ_ACTION_OUT:
                nn_req_action_send (req);
                return;
            case NN_REQ_ACTION_SENT:

                /*  New request was sent while the old one was still being
                    processed. Cancel the old request first. */
                nn_timer_stop (&req->timer);
                req->state = NN_REQ_STATE_CANCELLING;
                return;
            default:
                nn_assert (0);
            }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  Request was submitted. Waiting for reply.                                 */
/******************************************************************************/
    case NN_REQ_STATE_ACTIVE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_REQ_ACTION_IN:

                /*  Reply arrived. */
                nn_timer_stop (&req->timer);
                req->state = NN_REQ_STATE_STOPPING_TIMER;
                return;

            case NN_REQ_ACTION_SENT:

                /*  New request was sent while the old one was still being
                    processed. Cancel the old request first. */
                nn_timer_stop (&req->timer);
                req->state = NN_REQ_STATE_CANCELLING;
                return;

            default:
                nn_assert (0);
            }
        
        case NN_REQ_SRC_RESEND_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&req->timer);
                req->state = NN_REQ_STATE_TIMED_OUT;
                return;
            default:
                nn_assert (0);
            }
        
        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  TIMED_OUT state.                                                          */
/*  Waiting for reply has timer out. Stopping the timer. Afterwards, we'll    */
/*  re-send the request.                                                      */
/******************************************************************************/
    case NN_REQ_STATE_TIMED_OUT:
        switch (src) {

        case NN_REQ_SRC_RESEND_TIMER:
            switch (type) {
            case NN_TIMER_STOPPED:
                nn_req_action_send (req);
                return;
            default:
                nn_assert (0);
            }

        case NN_FSM_ACTION:
            switch (type) {
            case NN_REQ_ACTION_SENT:
                req->state = NN_REQ_STATE_CANCELLING;
                return;
            default:
                nn_assert (0);
            }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  CANCELLING state.                                                         */
/*  Request was canceled. Waiting till the timer is stopped.                  */
/******************************************************************************/
    case NN_REQ_STATE_CANCELLING:
        switch (src) {

        case NN_REQ_SRC_RESEND_TIMER:
            switch (type) {
            case NN_TIMER_STOPPED:
                nn_req_action_send (req);
                return;
            default:
                nn_assert (0);
            }

        case NN_FSM_ACTION:
             switch (type) {
             case NN_REQ_ACTION_SENT:
                 return;
             default:
                 nn_assert (0);
             }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  STOPPING_TIMER state.                                                     */
/*  Reply was delivered. Waiting till the timer is stopped.                   */
/******************************************************************************/
    case NN_REQ_STATE_STOPPING_TIMER:
        switch (src) {

        case NN_REQ_SRC_RESEND_TIMER:

            switch (type) {
            case NN_TIMER_STOPPED:
                req->state = NN_REQ_STATE_DONE;
                return;
            default:
                nn_assert (0);
            }

        case NN_FSM_ACTION:
            switch (type) {
            case NN_REQ_ACTION_SENT:
                req->state = NN_REQ_STATE_CANCELLING;
                return;
            default:
                nn_assert (0);
            }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  DONE state.                                                               */
/*  Reply was received but not yet retrieved by the user.                     */
/******************************************************************************/
    case NN_REQ_STATE_DONE:
        switch (src) {

        case NN_FSM_ACTION:
             switch (type) {
             case NN_REQ_ACTION_RECEIVED:
                 req->state = NN_REQ_STATE_PASSIVE;
                 return;
             case NN_REQ_ACTION_SENT:
                 nn_req_action_send (req);
                 return;
             default:
                 nn_assert (0);
             }

        default:
            nn_assert (0);
        }

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_assert (0);
    }
}
Exemple #12
0
static void nn_bipc_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_bipc *bipc;
    struct nn_list_item *it;
    struct nn_aipc *aipc;

    bipc = nn_cont (self, struct nn_bipc, fsm);

/******************************************************************************/
/*  STOP procedure.                                                           */
/******************************************************************************/
    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_aipc_stop (bipc->aipc);
        bipc->state = NN_BIPC_STATE_STOPPING_AIPC;
    }
    if (nn_slow (bipc->state == NN_BIPC_STATE_STOPPING_AIPC)) {
        if (!nn_aipc_isidle (bipc->aipc))
            return;
        nn_aipc_term (bipc->aipc);
        nn_free (bipc->aipc);
        bipc->aipc = NULL;
        nn_usock_stop (&bipc->usock);
        bipc->state = NN_BIPC_STATE_STOPPING_USOCK;
    }
    if (nn_slow (bipc->state == NN_BIPC_STATE_STOPPING_USOCK)) {
       if (!nn_usock_isidle (&bipc->usock))
            return;
        for (it = nn_list_begin (&bipc->aipcs);
              it != nn_list_end (&bipc->aipcs);
              it = nn_list_next (&bipc->aipcs, it)) {
            aipc = nn_cont (it, struct nn_aipc, item);
            nn_aipc_stop (aipc);
        }
        bipc->state = NN_BIPC_STATE_STOPPING_AIPCS;
        goto aipcs_stopping;
    }
    if (nn_slow (bipc->state == NN_BIPC_STATE_STOPPING_AIPCS)) {
        nn_assert (src == NN_BIPC_SRC_AIPC && type == NN_AIPC_STOPPED);
        aipc = (struct nn_aipc *) srcptr;
        nn_list_erase (&bipc->aipcs, &aipc->item);
        nn_aipc_term (aipc);
        nn_free (aipc);
        
        /*  If there are no more aipc state machines, we can stop the whole
            bipc object. */
aipcs_stopping:
        if (nn_list_empty (&bipc->aipcs)) {
            bipc->state = NN_BIPC_STATE_IDLE;
            nn_fsm_stopped_noevent (&bipc->fsm);
            nn_epbase_stopped (&bipc->epbase);
            return;
        }

        return;
    }

    switch (bipc->state) {

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

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_bipc_start_listening (bipc);
                nn_bipc_start_accepting (bipc);
                bipc->state = NN_BIPC_STATE_ACTIVE;
                return;
            default:
                nn_fsm_bad_action (bipc->state, src, type);
            }

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

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  The execution is yielded to the aipc state machine in this state.         */
/******************************************************************************/
    case NN_BIPC_STATE_ACTIVE:
        if (srcptr == bipc->aipc) {
            switch (type) {
            case NN_AIPC_ACCEPTED:

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

                /*  Start waiting for a new incoming connection. */
                nn_bipc_start_accepting (bipc);

                return;

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

        /*  For all remaining events we'll assume they are coming from one
            of remaining child aipc objects. */
        nn_assert (src == NN_BIPC_SRC_AIPC);
        aipc = (struct nn_aipc*) srcptr;
        switch (type) {
        case NN_AIPC_ERROR:
            nn_aipc_stop (aipc);
            return;
        case NN_AIPC_STOPPED:
            nn_list_erase (&bipc->aipcs, &aipc->item);
            nn_aipc_term (aipc);
            nn_free (aipc);
            return;
        default:
            nn_fsm_bad_action (bipc->state, src, type);
        }

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (bipc->state, src, type);
    }
}
Exemple #13
0
static void nn_surveyor_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    int rc;
    struct nn_surveyor *surveyor;

    surveyor = nn_cont (self, struct nn_surveyor, fsm);

/******************************************************************************/
/*  STOP procedure.                                                           */
/******************************************************************************/
    if (nn_slow (src== NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_timer_stop (&surveyor->timer);
        surveyor->state = NN_SURVEYOR_STATE_STOPPING;
    }
    if (nn_slow (surveyor->state == NN_SURVEYOR_STATE_STOPPING)) {
        if (!nn_timer_isidle (&surveyor->timer))
            return;
        surveyor->state = NN_SURVEYOR_STATE_IDLE;
        nn_fsm_stopped_noevent (&surveyor->fsm);
        nn_sockbase_stopped (&surveyor->xsurveyor.sockbase);
        return;
    }

    switch (surveyor->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/*  The socket was created recently.                                          */
/******************************************************************************/
    case NN_SURVEYOR_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                surveyor->state = NN_SURVEYOR_STATE_PASSIVE;
                return;
            default:
                nn_fsm_bad_action (surveyor->state, src, type);
            }

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

/******************************************************************************/
/*  PASSIVE state.                                                            */
/*  There's no survey going on.                                               */
/******************************************************************************/
    case NN_SURVEYOR_STATE_PASSIVE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_SURVEYOR_ACTION_START:
                rc = nn_xsurveyor_send (&surveyor->xsurveyor.sockbase,
                    &surveyor->tosend);
                errnum_assert (rc == 0, -rc);
                nn_timer_start (&surveyor->timer, surveyor->deadline);
                surveyor->state = NN_SURVEYOR_STATE_ACTIVE;
                return;

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

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

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  Survey was sent, waiting for responses.                                   */
/******************************************************************************/
    case NN_SURVEYOR_STATE_ACTIVE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_SURVEYOR_ACTION_CANCEL:
                nn_timer_stop (&surveyor->timer);
                surveyor->state = NN_SURVEYOR_STATE_CANCELLING;
                return;
            default:
                nn_fsm_bad_action (surveyor->state, src, type);
            }

        case NN_SURVEYOR_SRC_DEADLINE_TIMER:
            switch (type) {
            case NN_TIMER_TIMEOUT:
                nn_timer_stop (&surveyor->timer);
                surveyor->state = NN_SURVEYOR_STATE_STOPPING_TIMER;
                return;
            default:
                nn_fsm_bad_action (surveyor->state, src, type);
            }

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

/******************************************************************************/
/*  CANCELLING state.                                                         */
/*  Survey was cancelled, but the old timer haven't stopped yet. The new      */
/*  survey thus haven't been sent and is stored in 'tosend'.                  */
/******************************************************************************/
    case NN_SURVEYOR_STATE_CANCELLING:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_SURVEYOR_ACTION_CANCEL:
                return;
            default:
                nn_fsm_bad_action (surveyor->state, src, type);
            }

        case NN_SURVEYOR_SRC_DEADLINE_TIMER:
            switch (type) {
            case NN_TIMER_STOPPED:
                rc = nn_xsurveyor_send (&surveyor->xsurveyor.sockbase,
                    &surveyor->tosend);
                errnum_assert (rc == 0, -rc);
                nn_timer_start (&surveyor->timer, surveyor->deadline);
                surveyor->state = NN_SURVEYOR_STATE_ACTIVE;
                return;
            default:
                nn_fsm_bad_action (surveyor->state, src, type);
            }
        
        default:
            nn_fsm_bad_source (surveyor->state, src, type);
        }

/******************************************************************************/
/*  STOPPING_TIMER state.                                                     */
/*  Survey timeout expired. Now we are stopping the timer.                    */
/******************************************************************************/
    case NN_SURVEYOR_STATE_STOPPING_TIMER:
        switch (src) {

        case NN_SURVEYOR_SRC_DEADLINE_TIMER:
            switch (type) {
            case NN_TIMER_STOPPED:
                surveyor->state = NN_SURVEYOR_STATE_PASSIVE;
                return;
            default:
                nn_fsm_bad_action (surveyor->state, src, type);
            }

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

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (surveyor->state, src, type);
    }
}
Exemple #14
0
static void nn_bws_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_bws *bws;
    struct nn_list_item *it;
    struct nn_aws *aws;

    bws = nn_cont (self, struct nn_bws, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        if (bws->aws) {
            nn_aws_stop (bws->aws);
            bws->state = NN_BWS_STATE_STOPPING_AWS;
        }
        else {
            bws->state = NN_BWS_STATE_STOPPING_USOCK;
        }
    }
    if (nn_slow (bws->state == NN_BWS_STATE_STOPPING_AWS)) {
        if (!nn_aws_isidle (bws->aws))
            return;
        nn_aws_term (bws->aws);
        nn_free (bws->aws);
        bws->aws = NULL;
        nn_usock_stop (&bws->usock);
        bws->state = NN_BWS_STATE_STOPPING_USOCK;
    }
    if (nn_slow (bws->state == NN_BWS_STATE_STOPPING_USOCK)) {
       if (!nn_usock_isidle (&bws->usock))
            return;
        for (it = nn_list_begin (&bws->awss);
              it != nn_list_end (&bws->awss);
              it = nn_list_next (&bws->awss, it)) {
            aws = nn_cont (it, struct nn_aws, item);
            nn_aws_stop (aws);
        }
        bws->state = NN_BWS_STATE_STOPPING_AWSS;
        goto awss_stopping;
    }
    if (nn_slow (bws->state == NN_BWS_STATE_STOPPING_AWSS)) {
        nn_assert (src == NN_BWS_SRC_AWS && type == NN_AWS_STOPPED);
        aws = (struct nn_aws *) srcptr;
        nn_list_erase (&bws->awss, &aws->item);
        nn_aws_term (aws);
        nn_free (aws);

        /*  If there are no more aws state machines, we can stop the whole
            bws object. */
awss_stopping:
        if (nn_list_empty (&bws->awss)) {
            bws->state = NN_BWS_STATE_IDLE;
            nn_fsm_stopped_noevent (&bws->fsm);
            nn_epbase_stopped (&bws->epbase);
            return;
        }

        return;
    }

    nn_fsm_bad_action (bws->state, src, type);
}