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); } }
static void nn_aipc_handler (struct nn_fsm *self, int src, int type, void *srcptr) { struct nn_aipc *aipc; aipc = nn_cont (self, struct nn_aipc, fsm); /******************************************************************************/ /* STOP procedure. */ /******************************************************************************/ if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) { nn_sipc_stop (&aipc->sipc); aipc->state = NN_AIPC_STATE_STOPPING_SIPC_FINAL; } if (nn_slow (aipc->state == NN_AIPC_STATE_STOPPING_SIPC_FINAL)) { if (!nn_sipc_isidle (&aipc->sipc)) return; nn_usock_stop (&aipc->usock); aipc->state = NN_AIPC_STATE_STOPPING; } if (nn_slow (aipc->state == NN_AIPC_STATE_STOPPING)) { if (!nn_usock_isidle (&aipc->usock)) return; if (aipc->listener) { nn_assert (aipc->listener_owner.fsm); nn_usock_swap_owner (aipc->listener, &aipc->listener_owner); aipc->listener = NULL; aipc->listener_owner.src = 1; aipc->listener_owner.fsm = NULL; } aipc->state = NN_AIPC_STATE_IDLE; nn_fsm_stopped (&aipc->fsm, NN_AIPC_STOPPED); return; } switch (aipc->state) { /******************************************************************************/ /* IDLE state. */ /* The state machine wasn't yet started. */ /******************************************************************************/ case NN_AIPC_STATE_IDLE: switch (src) { case NN_FSM_ACTION: switch (type) { case NN_FSM_START: nn_usock_accept (&aipc->usock, aipc->listener); aipc->state = NN_AIPC_STATE_ACCEPTING; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* ACCEPTING state. */ /* Waiting for incoming connection. */ /******************************************************************************/ case NN_AIPC_STATE_ACCEPTING: switch (src) { case NN_AIPC_SRC_USOCK: switch (type) { case NN_USOCK_ACCEPTED: /* Return ownership of the listening socket to the parent. */ nn_usock_swap_owner (aipc->listener, &aipc->listener_owner); aipc->listener = NULL; aipc->listener_owner.src = -1; aipc->listener_owner.fsm = NULL; nn_fsm_raise (&aipc->fsm, &aipc->accepted, NN_AIPC_ACCEPTED); /* Start the sipc state machine. */ nn_usock_activate (&aipc->usock); nn_sipc_start (&aipc->sipc, &aipc->usock); aipc->state = NN_AIPC_STATE_ACTIVE; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* ACTIVE state. */ /******************************************************************************/ case NN_AIPC_STATE_ACTIVE: switch (src) { case NN_AIPC_SRC_SIPC: switch (type) { case NN_SIPC_ERROR: nn_sipc_stop (&aipc->sipc); aipc->state = NN_AIPC_STATE_STOPPING_SIPC; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* STOPPING_SIPC state. */ /******************************************************************************/ case NN_AIPC_STATE_STOPPING_SIPC: switch (src) { case NN_AIPC_SRC_SIPC: switch (type) { case NN_SIPC_STOPPED: nn_usock_stop (&aipc->usock); aipc->state = NN_AIPC_STATE_STOPPING_USOCK; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* STOPPING_USOCK state. */ /******************************************************************************/ case NN_AIPC_STATE_STOPPING_USOCK: switch (src) { case NN_AIPC_SRC_USOCK: switch (type) { case NN_USOCK_STOPPED: nn_fsm_raise (&aipc->fsm, &aipc->done, NN_AIPC_ERROR); aipc->state = NN_AIPC_STATE_DONE; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* Invalid state. */ /******************************************************************************/ default: nn_fsm_bad_state (aipc->state, src, type); } }
static void nn_cipc_handler (struct nn_fsm *self, int src, int type, NN_UNUSED void *srcptr) { struct nn_cipc *cipc; cipc = nn_cont (self, struct nn_cipc, fsm); switch (cipc->state) { /******************************************************************************/ /* IDLE state. */ /* The state machine wasn't yet started. */ /******************************************************************************/ case NN_CIPC_STATE_IDLE: switch (src) { case NN_FSM_ACTION: switch (type) { case NN_FSM_START: nn_cipc_start_connecting (cipc); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* CONNECTING state. */ /* Non-blocking connect is under way. */ /******************************************************************************/ case NN_CIPC_STATE_CONNECTING: switch (src) { case NN_CIPC_SRC_USOCK: switch (type) { case NN_USOCK_CONNECTED: nn_sipc_start (&cipc->sipc, &cipc->usock); cipc->state = NN_CIPC_STATE_ACTIVE; nn_epbase_stat_increment (&cipc->epbase, NN_STAT_INPROGRESS_CONNECTIONS, -1); nn_epbase_stat_increment (&cipc->epbase, NN_STAT_ESTABLISHED_CONNECTIONS, 1); nn_epbase_clear_error (&cipc->epbase); return; case NN_USOCK_ERROR: nn_epbase_set_error (&cipc->epbase,nn_usock_geterrno (&cipc->usock),__FILE__,__LINE__); nn_usock_stop (&cipc->usock); cipc->state = NN_CIPC_STATE_STOPPING_USOCK; nn_epbase_stat_increment (&cipc->epbase, NN_STAT_INPROGRESS_CONNECTIONS, -1); nn_epbase_stat_increment (&cipc->epbase, NN_STAT_CONNECT_ERRORS, 1); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* ACTIVE state. */ /* Connection is established and handled by the sipc state machine. */ /******************************************************************************/ case NN_CIPC_STATE_ACTIVE: switch (src) { case NN_CIPC_SRC_SIPC: switch (type) { case NN_SIPC_ERROR: nn_sipc_stop (&cipc->sipc); cipc->state = NN_CIPC_STATE_STOPPING_SIPC; nn_epbase_stat_increment (&cipc->epbase, NN_STAT_BROKEN_CONNECTIONS, 1); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* STOPPING_SIPC state. */ /* sipc object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CIPC_STATE_STOPPING_SIPC: switch (src) { case NN_CIPC_SRC_SIPC: switch (type) { case NN_USOCK_SHUTDOWN: return; case NN_SIPC_STOPPED: nn_usock_stop (&cipc->usock); cipc->state = NN_CIPC_STATE_STOPPING_USOCK; return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* STOPPING_USOCK state. */ /* usock object was asked to stop but it haven't stopped yet. */ /******************************************************************************/ case NN_CIPC_STATE_STOPPING_USOCK: switch (src) { case NN_CIPC_SRC_USOCK: switch (type) { case NN_USOCK_SHUTDOWN: return; case NN_USOCK_STOPPED: nn_backoff_start (&cipc->retry); cipc->state = NN_CIPC_STATE_WAITING; return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* WAITING state. */ /* Waiting before re-connection is attempted. This way we won't overload */ /* the system by continuous re-connection attemps. */ /******************************************************************************/ case NN_CIPC_STATE_WAITING: switch (src) { case NN_CIPC_SRC_RECONNECT_TIMER: switch (type) { case NN_BACKOFF_TIMEOUT: nn_backoff_stop (&cipc->retry); cipc->state = NN_CIPC_STATE_STOPPING_BACKOFF; return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* STOPPING_BACKOFF state. */ /* backoff object was asked to stop, but it haven't stopped yet. */ /******************************************************************************/ case NN_CIPC_STATE_STOPPING_BACKOFF: switch (src) { case NN_CIPC_SRC_RECONNECT_TIMER: switch (type) { case NN_BACKOFF_STOPPED: nn_cipc_start_connecting (cipc); return; default: nn_fsm_bad_action (cipc->state, src, type); } default: nn_fsm_bad_source (cipc->state, src, type); } /******************************************************************************/ /* Invalid state. */ /******************************************************************************/ default: nn_fsm_bad_state (cipc->state, src, type); } }
static void nn_aipc_handler (struct nn_fsm *self, int src, int type, void *srcptr) { struct nn_aipc *aipc; int val; size_t sz; aipc = nn_cont (self, struct nn_aipc, fsm); switch (aipc->state) { /******************************************************************************/ /* IDLE state. */ /* The state machine wasn't yet started. */ /******************************************************************************/ case NN_AIPC_STATE_IDLE: switch (src) { case NN_FSM_ACTION: switch (type) { case NN_FSM_START: nn_usock_accept (&aipc->usock, aipc->listener); aipc->state = NN_AIPC_STATE_ACCEPTING; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* ACCEPTING state. */ /* Waiting for incoming connection. */ /******************************************************************************/ case NN_AIPC_STATE_ACCEPTING: switch (src) { case NN_AIPC_SRC_USOCK: switch (type) { case NN_USOCK_ACCEPTED: /* Set the relevant socket options. */ sz = sizeof (val); nn_epbase_getopt (aipc->epbase, NN_SOL_SOCKET, NN_SNDBUF, &val, &sz); nn_assert (sz == sizeof (val)); nn_usock_setsockopt (&aipc->usock, SOL_SOCKET, SO_SNDBUF, &val, sizeof (val)); sz = sizeof (val); nn_epbase_getopt (aipc->epbase, NN_SOL_SOCKET, NN_RCVBUF, &val, &sz); nn_assert (sz == sizeof (val)); nn_usock_setsockopt (&aipc->usock, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val)); /* Return ownership of the listening socket to the parent. */ nn_usock_swap_owner (aipc->listener, &aipc->listener_owner); aipc->listener = NULL; aipc->listener_owner.src = -1; aipc->listener_owner.fsm = NULL; nn_fsm_raise (&aipc->fsm, &aipc->accepted, NN_AIPC_ACCEPTED); /* Start the sipc state machine. */ nn_usock_activate (&aipc->usock); nn_sipc_start (&aipc->sipc, &aipc->usock); aipc->state = NN_AIPC_STATE_ACTIVE; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* ACTIVE state. */ /******************************************************************************/ case NN_AIPC_STATE_ACTIVE: switch (src) { case NN_AIPC_SRC_SIPC: switch (type) { case NN_SIPC_ERROR: nn_sipc_stop (&aipc->sipc); aipc->state = NN_AIPC_STATE_STOPPING_SIPC; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* STOPPING_SIPC state. */ /******************************************************************************/ case NN_AIPC_STATE_STOPPING_SIPC: switch (src) { case NN_AIPC_SRC_SIPC: switch (type) { case NN_SIPC_STOPPED: nn_usock_stop (&aipc->usock); aipc->state = NN_AIPC_STATE_STOPPING_USOCK; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* STOPPING_USOCK state. */ /******************************************************************************/ case NN_AIPC_STATE_STOPPING_USOCK: switch (src) { case NN_AIPC_SRC_USOCK: switch (type) { case NN_USOCK_STOPPED: nn_fsm_raise (&aipc->fsm, &aipc->done, NN_AIPC_ERROR); aipc->state = NN_AIPC_STATE_DONE; return; default: nn_fsm_bad_action (aipc->state, src, type); } default: nn_fsm_bad_source (aipc->state, src, type); } /******************************************************************************/ /* Invalid state. */ /******************************************************************************/ default: nn_fsm_bad_state (aipc->state, src, type); } }