/** ======================================================================== * ========================================================================= */ void psl_sme_begin_transition(PslSmeMachineBase* const pFsm, PslSmeStateBase* const pTargetState, const void* const beginEvtArg, size_t const beginEvtArgSize, const char* const requesterFuncName) { PSL_ASSERT(pFsm); PSL_ASSERT(pTargetState); if (!pFsm->inEvtDispatch) { PSL_LOG_FATAL("%s (fsm=%p/%s): FATAL ERROR: %s() requested transition " \ "to state=%s from non-event-handler scope", __func__, pFsm, FsmDbgPeekMachineName(&pFsm->base), requesterFuncName, FsmDbgPeekStateName(&pTargetState->base)); PSL_ASSERT(pFsm->inEvtDispatch); } if (pFsm->beginEvtData_.reqArgSize) { PSL_LOG_FATAL( "%s (fsm=%p/%s): ERROR: Prior kFsmEventBegin arg not " \ "reaped: prior targetState=%s, arg size=%zd, " \ "requester=%s", __func__, pFsm, FsmDbgPeekMachineName(&pFsm->base), (pFsm->beginEvtData_.reqTargetState ? FsmDbgPeekStateName(&pFsm->beginEvtData_.reqTargetState->base) : "(NULL)"), pFsm->beginEvtData_.reqArgSize, pFsm->beginEvtData_.requesterFuncName); PSL_ASSERT(!pFsm->beginEvtData_.reqArgSize); } if (beginEvtArg) { PSL_ASSERT(beginEvtArgSize > 0 && beginEvtArgSize <= pFsm->beginEvtData_.beginArgBufSize); pFsm->beginEvtData_.reqTargetState = pTargetState; pFsm->beginEvtData_.reqArgSize = beginEvtArgSize; pFsm->beginEvtData_.requesterFuncName = requesterFuncName; memcpy(pFsm->beginEvtData_.beginRequestArgBuf, beginEvtArg, beginEvtArgSize); } FsmBeginTransition(&pFsm->base, &pTargetState->base); }
/** ======================================================================== * ========================================================================= */ static PslSmeEventStatus chan_fsm_alive_state_handler(PslChanFsmAliveState* const pState, PslChanFsm* const pFsm, PslSmeEventId const evtId, const PslChanFsmEvtArg* const evtArg) { switch (evtId) { case kFsmEventEnterScope: case kFsmEventExitScope: case kFsmEventBegin: return kPslSmeEventStatus_success; break; case PSL_CHAN_FSM_EVT_CLOSE: psl_chan_fsm_goto_closed_state(pFsm); return kPslSmeEventStatus_success; break; case PSL_CHAN_FSM_EVT_FINALIZE: psl_chan_fsm_goto_final_state(pFsm); return kPslSmeEventStatus_success; break; case PSL_CHAN_FSM_EVT_CHECK_IO: return psl_chan_fsm_evt_make_simple_CHECK_IO_response( &evtArg->checkIO, kPslChanFsmEvtIOReadyHint_notReady, PSL_INVALID_FD); break; default: break; } if (evtId >= kFsmEventFirstUserEvent) { PSL_LOG_ERROR( "%s (%p): %s.%s: ERROR: Operation not allowed: evtId=%d", __func__, pFsm, FsmDbgPeekMachineName(&pFsm->base.base), FsmDbgPeekStateName(&pState->base.base), evtId); psl_chan_fsm_set_last_error(pFsm, kPslChanFsmErrorSource_psl, PSL_ERR_NOT_ALLOWED); return kPslSmeEventStatus_errorCatchAll; } else { return kPslSmeEventStatus_success; } }//chan_fsm_alive_state_handler
/** ======================================================================== * ========================================================================= */ static PslSmeEventStatus chan_fsm_final_state_handler(PslChanFsmFinalState* const pState, PslChanFsm* const pFsm, PslSmeEventId const evtId, const PslChanFsmEvtArg* const evtArg) { switch (evtId) { case kFsmEventEnterScope: PSL_ASSERT(pFsm->fsmClosed); ///< we should have been closed first chan_fsm_destroy_widgets(pFsm); pFsm->fsmFinalized = true; /// FALLTHROUGH case kFsmEventExitScope: /// FALLTHROUGH case kFsmEventBegin: return kPslSmeEventStatus_success; break; default: if (evtId >= kFsmEventFirstUserEvent) { /// We don't expect any other events in the final state, since /// we're supposed to be an ephemeral state used only during /// destruction of the FSM instance. PSL_LOG_FATAL("%s (fsm=%p): ERROR: %s.%s received unexpected " \ "event %d", __func__, pFsm, FsmDbgPeekMachineName(&pFsm->base.base), FsmDbgPeekStateName(&pState->base.base), evtId); PSL_ASSERT(false && "unexpected event in 'final' state"); } break; } return kPslSmeEventStatus_passToParent; }