static int nn_surveyor_send (struct nn_sockbase *self, struct nn_msg *msg) { int rc; struct nn_surveyor *surveyor; surveyor = nn_cont (self, struct nn_surveyor, xsurveyor.sockbase); /* Cancel any ongoing survey. */ if (nn_slow (surveyor->flags & NN_SURVEYOR_INPROGRESS)) { surveyor->flags &= ~NN_SURVEYOR_INPROGRESS; nn_timer_stop (&surveyor->deadline_timer); } /* Generate new survey ID. */ ++surveyor->surveyid; /* Tag the survey body with survey ID. */ nn_assert (nn_chunkref_size (&msg->hdr) == 0); nn_chunkref_term (&msg->hdr); nn_chunkref_init (&msg->hdr, 4); nn_putl (nn_chunkref_data (&msg->hdr), surveyor->surveyid); /* Send the survey. */ rc = nn_xsurveyor_send (&surveyor->xsurveyor.sockbase, msg); errnum_assert (rc == 0, -rc); surveyor->flags |= NN_SURVEYOR_INPROGRESS; /* Set up the re-send timer. */ nn_timer_start (&surveyor->deadline_timer, surveyor->deadline); return 0; }
static void nn_surveyor_resend (struct nn_surveyor *self) { int rc; struct nn_msg msg; nn_msg_cp (&msg, &self->tosend); rc = nn_xsurveyor_send (&self->xsurveyor.sockbase, &msg); errnum_assert (rc == 0, -rc); }
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); } }