Esempio n. 1
0
void nn_priolist_rm (struct nn_priolist *self, struct nn_pipe *pipe,
    struct nn_priolist_data *data)
{
    struct nn_priolist_slot *slot;
    struct nn_list_item *it;

    /*  Non-active pipes don't need any special processing. */
    if (!nn_list_item_isinlist (&data->item)) {
        nn_list_item_term (&data->item);
        return;
    }

    /*  If the pipe being removed is not current, we can simply erase it
        from the list. */
    slot = &self->slots [data->priority - 1];
    if (slot->current != data) {
        nn_list_erase (&slot->pipes, &data->item);
        nn_list_item_term (&data->item);
        return;
    }

    /*  Advance the current pointer (with wrap-over). */
    it = nn_list_erase (&slot->pipes, &data->item);
    slot->current = nn_cont (it, struct nn_priolist_data, item);
    nn_list_item_term (&data->item);
    if (!slot->current) {
        it = nn_list_begin (&slot->pipes);
        slot->current = nn_cont (it, struct nn_priolist_data, item);
    }
Esempio n. 2
0
static void nn_global_term (void)
{
#if defined NN_HAVE_WINDOWS
    int rc;
#endif
    struct nn_list_item *it;
    struct nn_transport *tp;

    /*  If there are no sockets remaining, uninitialise the global context. */
    nn_assert (self.socks);
    if (self.nsocks > 0)
        return;

    /*  Stop the FSM  */
    nn_ctx_enter (&self.ctx);
    nn_fsm_stop (&self.fsm);
    nn_ctx_leave (&self.ctx);

    /*  Shut down the worker threads. */
    nn_pool_term (&self.pool);

    /* Terminate ctx mutex */
    nn_ctx_term (&self.ctx);

    /*  Ask all the transport to deallocate their global resources. */
    while (!nn_list_empty (&self.transports)) {
        it = nn_list_begin (&self.transports);
        tp = nn_cont (it, struct nn_transport, item);
        if (tp->term)
            tp->term ();
        nn_list_erase (&self.transports, it);
    }

    /*  For now there's nothing to deallocate about socket types, however,
        let's remove them from the list anyway. */
    while (!nn_list_empty (&self.socktypes))
        nn_list_erase (&self.socktypes, nn_list_begin (&self.socktypes));

    /*  Final deallocation of the nn_global object itself. */
    nn_list_term (&self.socktypes);
    nn_list_term (&self.transports);
    nn_free (self.socks);

    /*  This marks the global state as uninitialised. */
    self.socks = NULL;

    /*  Shut down the memory allocation subsystem. */
    nn_alloc_term ();

    /*  On Windows, uninitialise the socket library. */
#if defined NN_HAVE_WINDOWS
    rc = WSACleanup ();
    nn_assert (rc == 0);
#endif
}
Esempio n. 3
0
void nn_priolist_advance (struct nn_priolist *self, int release)
{
    struct nn_priolist_slot *slot;
    struct nn_list_item *it;

    nn_assert (self->current > 0);
    slot = &self->slots [self->current - 1];

    /*  Move slot's current pointer to the next pipe. */
    if (release)
        it = nn_list_erase (&slot->pipes, &slot->current->item);
    else
        it = nn_list_next (&slot->pipes, &slot->current->item);
    if (!it)
        it = nn_list_begin (&slot->pipes);
    slot->current = nn_cont (it, struct nn_priolist_data, item);

    /* If there are no more pipes in this slot, find a non-empty slot with
       lower priority. */
    while (nn_list_empty (&slot->pipes)) {
        ++self->current;
        if (self->current > NN_PRIOLIST_SLOTS) {
            self->current = -1;
            return;
        }
        slot = &self->slots [self->current - 1];
    }
}
Esempio n. 4
0
void nn_priolist_rm (struct nn_priolist *self, struct nn_pipe *pipe,
    struct nn_priolist_data *data)
{
    if (nn_list_item_isinlist (&data->item))
        nn_list_erase (&self->slots [data->priority - 1].pipes, &data->item);
    nn_list_item_term (&data->item);
}
Esempio n. 5
0
/*  Deallocate a message chunk and remove it from array. */
static void nn_msg_chunk_term (struct msg_chunk *it,
    struct nn_list *msg_array)
{
    nn_chunkref_term (&it->chunk);
    nn_list_erase (msg_array, &it->item);
    nn_list_item_term (&it->item);
    nn_free (it);
}
Esempio n. 6
0
File: ctx.c Progetto: jjrdn/nanomsg
static void nn_ctx_term (void)
{
#if defined NN_HAVE_WINDOWS
    int rc;
#endif
    struct nn_list_item *it;

    /*  If there are no sockets remaining, uninitialise the global context. */
    nn_assert (self.socks);
    if (self.nsocks > 0)
        return;

#if defined NN_LATENCY_MONITOR
    nn_latmon_term ();
#endif

    /*  Ask all the transport to deallocate their global resources. */
    while (!nn_list_empty (&self.transports)) {
        it = nn_list_begin (&self.transports);
        nn_cont (it, struct nn_transport, list)->term ();
        nn_list_erase (&self.transports, it);
    }

    /*  For now there's nothing to deallocate about socket types, however,
        let's remove them from the list anyway. */
    while (!nn_list_empty (&self.socktypes))
        nn_list_erase (&self.socktypes, nn_list_begin (&self.socktypes));

    /*  Final deallocation of the nn_ctx object itself. */
    nn_list_term (&self.socktypes);
    nn_list_term (&self.transports);
    nn_free (self.socks);

    /*  This marks the global state as uninitialised. */
    self.socks = NULL;

    /*  Shut down the memory allocation subsystem. */
    nn_alloc_term ();

    /*  On Windows, uninitialise the socket library. */
#if defined NN_HAVE_WINDOWS
    rc = WSACleanup ();
    nn_assert (rc == 0);
#endif
}
Esempio n. 7
0
void nn_dist_rm (struct nn_dist *self, struct nn_pipe *pipe,
    struct nn_dist_data *data)
{
    if (nn_list_item_isinlist (&data->item)) {
        --self->count;
        nn_list_erase (&self->pipes, &data->item);
    }
    nn_list_item_term (&data->item);
}
Esempio n. 8
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);
}
Esempio n. 9
0
File: bipc.c Progetto: antmd/nanomsg
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);
}
Esempio n. 10
0
int nn_dist_send (struct nn_dist *self, struct nn_msg *msg,
    struct nn_pipe *exclude)
{
    int rc;
    struct nn_list_item *it;
    struct nn_dist_data *data;
    struct nn_msg copy;

    /*  TODO: We can optimise for the case when there's only one outbound
        pipe here. No message copying is needed in such case. */

    /*  In the specific case when there are no outbound pipes. There's nowhere
        to send the message to. Deallocate it. */
    if (nn_slow (self->count) == 0) {
        nn_msg_term (msg);
        return 0;
    }

    /*  Send the message to all the subscribers. */
    nn_msg_bulkcopy_start (msg, self->count);
    it = nn_list_begin (&self->pipes);
    while (it != nn_list_end (&self->pipes)) {
       data = nn_cont (it, struct nn_dist_data, item);
       nn_msg_bulkcopy_cp (&copy, msg);
       if (nn_fast (data->pipe == exclude)) {
           nn_msg_term (&copy);
       }
       else {
           rc = nn_pipe_send (data->pipe, &copy);
           errnum_assert (rc >= 0, -rc);
           if (rc & NN_PIPE_RELEASE) {
               --self->count;
               it = nn_list_erase (&self->pipes, it);
               continue;
           }
       }
       it = nn_list_next (&self->pipes, it);
    }
    nn_msg_term (msg);

    return 0;
}
Esempio n. 11
0
int ftw_socket_destroy(struct ftw_socket ** const sock)
{
    int rc;

    /*  Preconditions expected of LabVIEW. */
    ftw_assert(sock);

    if (*sock == NULL) {
        errno = EBADF;
        return -1;
    }

    nn_mutex_lock(&(*sock)->callsite->sync);
    rc = ftw_socket_close(*sock);
    nn_list_erase(&(*sock)->callsite->active_sockets, &(*sock)->item);
    nn_mutex_unlock(&(*sock)->callsite->sync);
    ftw_assert(ftw_free(*sock) == mgNoErr);
    *sock = NULL;

    return rc;
}
Esempio n. 12
0
static void nn_sock_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_sock *sock;
    struct nn_list_item *it;
    struct nn_ep *ep;

    sock = nn_cont (self, struct nn_sock, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_assert (sock->state == NN_SOCK_STATE_ACTIVE ||
            sock->state == NN_SOCK_STATE_ZOMBIE);

        /*  Close sndfd and rcvfd. This should make any current
            select/poll using SNDFD and/or RCVFD exit. */
        if (!(sock->socktype->flags & NN_SOCKTYPE_FLAG_NORECV)) {
            nn_efd_term (&sock->rcvfd);
            memset (&sock->rcvfd, 0xcd, sizeof (sock->rcvfd));
        }
        if (!(sock->socktype->flags & NN_SOCKTYPE_FLAG_NOSEND)) {
            nn_efd_term (&sock->sndfd);
            memset (&sock->sndfd, 0xcd, sizeof (sock->sndfd));
        }

        /*  Ask all the associated endpoints to stop. */
        it = nn_list_begin (&sock->eps);
        while (it != nn_list_end (&sock->eps)) {
            ep = nn_cont (it, struct nn_ep, item);
            it = nn_list_next (&sock->eps, it);
            nn_list_erase (&sock->eps, &ep->item);
            nn_list_insert (&sock->sdeps, &ep->item,
                nn_list_end (&sock->sdeps));
            nn_ep_stop (ep);

        }
        sock->state = NN_SOCK_STATE_STOPPING_EPS;
        goto finish2;
    }
Esempio n. 13
0
int nn_sock_rm_ep (struct nn_sock *self, int eid)
{
    struct nn_list_item *it;
    struct nn_ep *ep;

    nn_ctx_enter (&self->ctx);

    /*  Find the specified enpoint. */
    ep = NULL;
    for (it = nn_list_begin (&self->eps);
          it != nn_list_end (&self->eps);
          it = nn_list_next (&self->eps, it)) {
        ep = nn_cont (it, struct nn_ep, item);
        if (ep->eid == eid)
            break;
        ep = NULL;
    }

    /*  The endpoint doesn't exist. */
    if (!ep) {
        nn_ctx_leave (&self->ctx);
        return -EINVAL;
    }

    /*  Move the endpoint from the list of active endpoints to the list
        of shutting down endpoints. */
    nn_list_erase (&self->eps, &ep->item);
    nn_list_insert (&self->sdeps, &ep->item, nn_list_end (&self->sdeps));

    /*  Ask the endpoint to stop. Actual terminatation may be delayed
        by the transport. */
    nn_ep_stop (ep);

    nn_ctx_leave (&self->ctx);

    return 0;
}
Esempio n. 14
0
void ftw_nanomsg_shutdown_active_sockets(struct ftw_socket_callsite *callsite)
{
    struct ftw_socket *sock;
    struct nn_list_item *it;

    /*  Preconditions expected of LabVIEW. */
    ftw_assert(callsite);
    nn_mutex_lock(&callsite->sync);

    ftw_debug("Shutting down sockets from Callsite %d", callsite->id);

    it = nn_list_begin(&callsite->active_sockets);
    while (it != NULL) {
        sock = nn_cont(it, struct ftw_socket, item);
        ftw_debug("Cleaning up active socket: %04d", sock->id);
        ftw_socket_close(sock);
        it = nn_list_erase(&callsite->active_sockets, it);
    }

    nn_list_term(&callsite->active_sockets);
    nn_mutex_unlock(&callsite->sync);

    return;
}
Esempio n. 15
0
static void nn_bipc_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_bipc *bipc;
    struct nn_aipc *aipc;

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

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

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

        case NN_BIPC_SRC_USOCK:
            switch (type) {
            case NN_USOCK_SHUTDOWN:
                return;
            case NN_USOCK_STOPPED:
                nn_backoff_start (&bipc->retry);
                bipc->state = NN_BIPC_STATE_WAITING;
                return;
            default:
                nn_fsm_bad_action (bipc->state, src, type);
            }

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

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

        case NN_BIPC_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_TIMEOUT:
                nn_backoff_stop (&bipc->retry);
                bipc->state = NN_BIPC_STATE_STOPPING_BACKOFF;
                return;
            default:
                nn_fsm_bad_action (bipc->state, src, type);
            }

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

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

        case NN_BIPC_SRC_RECONNECT_TIMER:
            switch (type) {
            case NN_BACKOFF_STOPPED:
                nn_bipc_start_listening (bipc);
                return;
            default:
                nn_fsm_bad_action (bipc->state, src, type);
            }

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

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (bipc->state, src, type);
    }
}
Esempio n. 16
0
File: ins.c Progetto: 4ker/nanomsg
void nn_ins_unbind (struct nn_ins_item *item)
{
    nn_mutex_lock (&self.sync);
    nn_list_erase (&self.bound, &item->item);
    nn_mutex_unlock (&self.sync);
}
Esempio n. 17
0
File: ins.c Progetto: 4ker/nanomsg
void nn_ins_disconnect (struct nn_ins_item *item)
{
    nn_mutex_lock (&self.sync);
    nn_list_erase (&self.connected, &item->item);
    nn_mutex_unlock (&self.sync);
}
Esempio n. 18
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);
}
Esempio n. 19
0
static void nn_bws_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_bws *bws;
    struct nn_aws *aws;

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

    switch (bws->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/******************************************************************************/
    case NN_BWS_STATE_IDLE:
        nn_assert (src == NN_FSM_ACTION);
        nn_assert (type == NN_FSM_START);
        bws->state = NN_BWS_STATE_ACTIVE;
        return;

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  The execution is yielded to the aws state machine in this state.          */
/******************************************************************************/
    case NN_BWS_STATE_ACTIVE:
        if (src == NN_BWS_SRC_USOCK) {
            nn_assert (type == NN_USOCK_SHUTDOWN || type == NN_USOCK_STOPPED);
            return;
        }

        /*  For all remaining events we'll assume they are coming from one
            of remaining child aws objects. */
        nn_assert (src == NN_BWS_SRC_AWS);
        aws = (struct nn_aws*) srcptr;
        switch (type) {
        case NN_AWS_ACCEPTED:

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

            /*  Start waiting for a new incoming connection. */
            nn_bws_start_accepting (bws);
            return;

        case NN_AWS_ERROR:
            nn_aws_stop (aws);
            return;
        case NN_AWS_STOPPED:
            nn_list_erase (&bws->awss, &aws->item);
            nn_aws_term (aws);
            nn_free (aws);
            return;
        default:
            nn_fsm_bad_action (bws->state, src, type);
        }

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (bws->state, src, type);
    }
}
Esempio n. 20
0
void nn_inproc_disconnect (struct nn_cinproc *cinproc)
{
    nn_mutex_lock (&self.sync);
    nn_list_erase (&self.connected, &cinproc->item);
    nn_mutex_unlock (&self.sync);
}
Esempio n. 21
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);
    }
}
Esempio n. 22
0
void nn_inproc_unbind (struct nn_binproc *binproc)
{
    nn_mutex_lock (&self.sync);
    nn_list_erase (&self.bound, &binproc->item);
    nn_mutex_unlock (&self.sync);
}
Esempio n. 23
0
void nn_inproc_ctx_disconnect (struct nn_inprocc *inprocc)
{
    nn_list_erase (&self.connected, &inprocc->list);
}
Esempio n. 24
0
static void nn_btcp_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_btcp *btcp;
    struct nn_atcp *atcp;

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

    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);
    }
}
Esempio n. 25
0
void nn_inproc_ctx_unbind (struct nn_inprocb *inprocb)
{
    nn_list_erase (&self.bound, &inprocb->list);
}