int nn_stcp_isidle(struct nn_stcp *self) { return nn_fsm_isidle(&self->fsm); }
void nn_usock_accept (struct nn_usock *self, struct nn_usock *listener) { int s; /* Start the actual accepting. */ if (nn_fsm_isidle(&self->fsm)) { nn_fsm_start (&self->fsm); nn_fsm_action (&self->fsm, NN_USOCK_ACTION_BEING_ACCEPTED); } nn_fsm_action (&listener->fsm, NN_USOCK_ACTION_ACCEPT); /* Try to accept new connection in synchronous manner. */ #if NN_HAVE_ACCEPT4 s = accept4 (listener->s, NULL, NULL, SOCK_CLOEXEC); #else s = accept (listener->s, NULL, NULL); #endif //printf("usock.%d -> accept errno.%d s.%d %s\n",self->s,errno,s,nn_strerror(errno)); /* Immediate success. */ if (nn_fast (s >= 0)) { /* Disassociate the listener socket from the accepted socket. Is useful if we restart accepting on ACCEPT_ERROR */ listener->asock = NULL; self->asock = NULL; nn_usock_init_from_fd (self, s); nn_fsm_action (&listener->fsm, NN_USOCK_ACTION_DONE); nn_fsm_action (&self->fsm, NN_USOCK_ACTION_DONE); return; } /* Detect a failure. Note that in ECONNABORTED case we simply ignore the error and wait for next connection in asynchronous manner. */ errno_assert (errno == EAGAIN || errno == EWOULDBLOCK || errno == ECONNABORTED || errno == ENFILE || errno == EMFILE || errno == ENOBUFS || errno == ENOMEM); /* Pair the two sockets. They are already paired in case previous attempt failed on ACCEPT_ERROR */ nn_assert (!self->asock || self->asock == listener); self->asock = listener; nn_assert (!listener->asock || listener->asock == self); listener->asock = self; /* Some errors are just ok to ignore for now. We also stop repeating any errors until next IN_FD event so that we are not in a tight loop and allow processing other events in the meantime */ if (nn_slow (errno != EAGAIN && errno != EWOULDBLOCK && errno != ECONNABORTED && errno != listener->errnum)) { PNACL_message("listen errno.%d\n",errno); listener->errnum = errno; listener->state = NN_USOCK_STATE_ACCEPTING_ERROR; nn_fsm_raise (&listener->fsm, &listener->event_error, NN_USOCK_ACCEPT_ERROR); return; } /* Ask the worker thread to wait for the new connection. */ nn_worker_execute (listener->worker, &listener->task_accept); }
int nn_slibfabric_isidle (struct nn_slibfabric *self) { return nn_fsm_isidle (&self->fsm); }
int nn_aipc_isidle (struct nn_aipc *self) { return nn_fsm_isidle (&self->fsm); }
int nn_usock_isidle (struct nn_usock *self) { return nn_fsm_isidle (&self->fsm); }
void nn_fsm_start (struct nn_fsm *self) { nn_assert (nn_fsm_isidle (self)); self->fn (self, NN_FSM_ACTION, NN_FSM_START, NULL); self->state = NN_FSM_STATE_ACTIVE; }
void nn_fsm_term (struct nn_fsm *self) { nn_assert (nn_fsm_isidle (self)); nn_fsm_event_term (&self->stopped); }
int nn_sws_isidle (struct nn_sws *self) { return nn_fsm_isidle (&self->fsm); }
int nn_timer_isidle (struct nn_timer *self) { return nn_fsm_isidle (&self->fsm); }
int nn_streamhdr_isidle (struct nn_streamhdr *self) { return nn_fsm_isidle (&self->fsm); }