static void nn_cws_handler (struct nn_fsm *self, int src, int type, NN_UNUSED void *srcptr) { struct nn_cws *cws; cws = nn_cont (self, struct nn_cws, fsm); switch (cws->state) { /******************************************************************************/ /* IDLE state. */ /* The state machine wasn't yet started. */ /******************************************************************************/ case NN_CWS_STATE_IDLE: switch (src) { case NN_FSM_ACTION: switch (type) { case NN_FSM_START: nn_cws_start_resolving (cws); return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* RESOLVING state. */ /* Name of the host to connect to is being resolved to get an IP address. */ /******************************************************************************/ case NN_CWS_STATE_RESOLVING: switch (src) { case NN_CWS_SRC_DNS: switch (type) { case NN_DNS_DONE: nn_dns_stop (&cws->dns); cws->state = NN_CWS_STATE_STOPPING_DNS; return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* STOPPING_DNS state. */ /* dns object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CWS_STATE_STOPPING_DNS: switch (src) { case NN_CWS_SRC_DNS: switch (type) { case NN_DNS_STOPPED: if (cws->dns_result.error == 0) { nn_cws_start_connecting (cws, &cws->dns_result.addr, cws->dns_result.addrlen); return; } nn_backoff_start (&cws->retry); cws->state = NN_CWS_STATE_WAITING; return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* CONNECTING state. */ /* Non-blocking connect is under way. */ /******************************************************************************/ case NN_CWS_STATE_CONNECTING: switch (src) { case NN_CWS_SRC_USOCK: switch (type) { case NN_USOCK_CONNECTED: nn_sws_start (&cws->sws, &cws->usock, NN_WS_CLIENT, nn_chunkref_data (&cws->resource), nn_chunkref_data (&cws->remote_host), cws->msg_type); cws->state = NN_CWS_STATE_ACTIVE; cws->peer_gone = 0; nn_ep_stat_increment (cws->ep, NN_STAT_INPROGRESS_CONNECTIONS, -1); nn_ep_stat_increment (cws->ep, NN_STAT_ESTABLISHED_CONNECTIONS, 1); nn_ep_clear_error (cws->ep); return; case NN_USOCK_ERROR: nn_ep_set_error (cws->ep, nn_usock_geterrno (&cws->usock)); nn_usock_stop (&cws->usock); cws->state = NN_CWS_STATE_STOPPING_USOCK; nn_ep_stat_increment (cws->ep, NN_STAT_INPROGRESS_CONNECTIONS, -1); nn_ep_stat_increment (cws->ep, NN_STAT_CONNECT_ERRORS, 1); return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* ACTIVE state. */ /* Connection is established and handled by the sws state machine. */ /******************************************************************************/ case NN_CWS_STATE_ACTIVE: switch (src) { case NN_CWS_SRC_SWS: switch (type) { case NN_SWS_RETURN_CLOSE_HANDSHAKE: /* Peer closed connection without intention to reconnect, or local endpoint failed remote because of invalid data. */ nn_sws_stop (&cws->sws); cws->state = NN_CWS_STATE_STOPPING_SWS; cws->peer_gone = 1; return; case NN_SWS_RETURN_ERROR: nn_sws_stop (&cws->sws); cws->state = NN_CWS_STATE_STOPPING_SWS; nn_ep_stat_increment (cws->ep, NN_STAT_BROKEN_CONNECTIONS, 1); return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* STOPPING_SWS state. */ /* sws object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CWS_STATE_STOPPING_SWS: switch (src) { case NN_CWS_SRC_SWS: switch (type) { case NN_USOCK_SHUTDOWN: return; case NN_SWS_RETURN_STOPPED: nn_usock_stop (&cws->usock); cws->state = NN_CWS_STATE_STOPPING_USOCK; return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* STOPPING_USOCK state. */ /* usock object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CWS_STATE_STOPPING_USOCK: switch (src) { case NN_CWS_SRC_USOCK: switch (type) { case NN_USOCK_SHUTDOWN: return; case NN_USOCK_STOPPED: /* If the peer has confirmed itself gone with a Closing Handshake, or if the local endpoint failed the remote, don't try to reconnect. */ if (!cws->peer_gone) { nn_backoff_start (&cws->retry); cws->state = NN_CWS_STATE_WAITING; } return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->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_CWS_STATE_WAITING: switch (src) { case NN_CWS_SRC_RECONNECT_TIMER: switch (type) { case NN_BACKOFF_TIMEOUT: nn_backoff_stop (&cws->retry); cws->state = NN_CWS_STATE_STOPPING_BACKOFF; return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* STOPPING_BACKOFF state. */ /* backoff object was asked to stop, but it haven't stopped yet. */ /******************************************************************************/ case NN_CWS_STATE_STOPPING_BACKOFF: switch (src) { case NN_CWS_SRC_RECONNECT_TIMER: switch (type) { case NN_BACKOFF_STOPPED: nn_cws_start_resolving (cws); return; default: nn_fsm_bad_action (cws->state, src, type); } default: nn_fsm_bad_source (cws->state, src, type); } /******************************************************************************/ /* Invalid state. */ /******************************************************************************/ default: nn_fsm_bad_state (cws->state, src, type); } }
static void nn_cipc_handler (struct nn_fsm *self, int src, int type, NN_UNUSED void *srcptr) { struct nn_cipc *cipc; cipc = nn_cont (self, struct nn_cipc, fsm); switch (cipc->state) { /******************************************************************************/ /* IDLE state. */ /* The state machine wasn't yet started. */ /******************************************************************************/ case NN_CIPC_STATE_IDLE: switch (src) { case NN_FSM_ACTION: switch (type) { case NN_FSM_START: nn_cipc_start_connecting (cipc); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* CONNECTING state. */ /* Non-blocking connect is under way. */ /******************************************************************************/ case NN_CIPC_STATE_CONNECTING: switch (src) { case NN_CIPC_SRC_USOCK: switch (type) { case NN_USOCK_CONNECTED: nn_sipc_start (&cipc->sipc, &cipc->usock); cipc->state = NN_CIPC_STATE_ACTIVE; nn_ep_stat_increment (cipc->ep, NN_STAT_INPROGRESS_CONNECTIONS, -1); nn_ep_stat_increment (cipc->ep, NN_STAT_ESTABLISHED_CONNECTIONS, 1); nn_ep_clear_error (cipc->ep); return; case NN_USOCK_ERROR: nn_ep_set_error (cipc->ep, nn_usock_geterrno (&cipc->usock)); nn_usock_stop (&cipc->usock); cipc->state = NN_CIPC_STATE_STOPPING_USOCK; nn_ep_stat_increment (cipc->ep, NN_STAT_INPROGRESS_CONNECTIONS, -1); nn_ep_stat_increment (cipc->ep, NN_STAT_CONNECT_ERRORS, 1); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* ACTIVE state. */ /* Connection is established and handled by the sipc state machine. */ /******************************************************************************/ case NN_CIPC_STATE_ACTIVE: switch (src) { case NN_CIPC_SRC_SIPC: switch (type) { case NN_SIPC_ERROR: nn_sipc_stop (&cipc->sipc); cipc->state = NN_CIPC_STATE_STOPPING_SIPC; nn_ep_stat_increment (cipc->ep, NN_STAT_BROKEN_CONNECTIONS, 1); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* STOPPING_SIPC state. */ /* sipc object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CIPC_STATE_STOPPING_SIPC: switch (src) { case NN_CIPC_SRC_SIPC: switch (type) { case NN_USOCK_SHUTDOWN: return; case NN_SIPC_STOPPED: nn_usock_stop (&cipc->usock); cipc->state = NN_CIPC_STATE_STOPPING_USOCK; return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* STOPPING_USOCK state. */ /* usock object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CIPC_STATE_STOPPING_USOCK: switch (src) { case NN_CIPC_SRC_USOCK: switch (type) { case NN_USOCK_SHUTDOWN: return; case NN_USOCK_STOPPED: nn_backoff_start (&cipc->retry); cipc->state = NN_CIPC_STATE_WAITING; return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* WAITING state. */ /* Waiting before re-connection is attempted. This way we won't overload */ /* the system by continuous re-connection attemps. */ /******************************************************************************/ case NN_CIPC_STATE_WAITING: switch (src) { case NN_CIPC_SRC_RECONNECT_TIMER: switch (type) { case NN_BACKOFF_TIMEOUT: nn_backoff_stop (&cipc->retry); cipc->state = NN_CIPC_STATE_STOPPING_BACKOFF; return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* STOPPING_BACKOFF state. */ /* backoff object was asked to stop, but it haven't stopped yet. */ /******************************************************************************/ case NN_CIPC_STATE_STOPPING_BACKOFF: switch (src) { case NN_CIPC_SRC_RECONNECT_TIMER: switch (type) { case NN_BACKOFF_STOPPED: nn_cipc_start_connecting (cipc); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* Invalid state. */ /******************************************************************************/ default: nn_fsm_bad_state (cipc->state, src, type); } }
void nn_epbase_set_error(struct nn_epbase *self,int32_t errnum,char *fname,int32_t linenum) { nn_ep_set_error(self->ep,errnum,fname,linenum); }