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); }
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 }
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]; } }
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); }
/* 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); }
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 }
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); }
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); }
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); }
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 (©, msg); if (nn_fast (data->pipe == exclude)) { nn_msg_term (©); } else { rc = nn_pipe_send (data->pipe, ©); 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; }
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; }
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; }
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; }
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; }
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); } }
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); }
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); }
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); }
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); } }
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); }
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); } }
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); }
void nn_inproc_ctx_disconnect (struct nn_inprocc *inprocc) { nn_list_erase (&self.connected, &inprocc->list); }
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); } }
void nn_inproc_ctx_unbind (struct nn_inprocb *inprocb) { nn_list_erase (&self.bound, &inprocb->list); }