/** ======================================================================== * ========================================================================= */ 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); }
/** ======================================================================== * ========================================================================= */ PslMultiFdWatchSource* psl_multi_fd_watch_new(void) { GSource* const base = g_source_new(&psl_multi_fd_watch_funcs, sizeof(PslMultiFdWatchSource)); PslMultiFdWatchSource* const source = (PslMultiFdWatchSource*)base; if (!base) { goto error_cleanup; } /** * @note g_source_new returns a zero-initialized structure with * the base (GSource) "class" properly set up and with * reference count = 1. */ source->restartTimer = true; source->timeoutMillisec = MULTI_FD_WATCH_INFINITE_MSEC; source->descTable = g_hash_table_new_full(&g_direct_hash, &g_direct_equal, NULL /*key_destroy_func*/, &g_free/*value_destroy_func*/); if (!source->descTable) { goto error_cleanup; } PSL_LOG_DEBUGLOW("%s (watch=%p): descriptor table=%p", __func__, source, source->descTable); source->cachedReadyPollFdArray = g_array_new(false/*zero_terminated*/, false/*clear_*/, sizeof(PslMultiFdPollRec)); if (!source->cachedReadyPollFdArray) { goto error_cleanup; } PSL_LOG_DEBUG("%s (watch=%p): new watch created", __func__, source); return source; error_cleanup: PSL_LOG_FATAL("%s: FAILED (out of mem?)", __func__); if (base) { g_source_unref(base); } return NULL; }
/* ========================================================================= * ========================================================================= */ PslError PmSockThreadCtxNewFromGMain(GMainContext* gmainCtx, const char* const userLabel, PmSockThreadContext** const pThreadCtx) { PSL_LOG_DEBUG("%s: pThreadCtx=%p, userLabel=\"%s\", gmaincxt=%p", __func__, pThreadCtx, PSL_LOG_MAKE_SAFE_STR(userLabel), gmainCtx); PSL_ASSERT(pThreadCtx); *pThreadCtx = NULL; struct PmSockThreadContext_* const ctx = g_new0(struct PmSockThreadContext_, 1); PslError pslerr = 0; if (!ctx) { pslerr = PSL_ERR_MEM; goto error_cleanup; } psl_refcount_init(&ctx->refCount_, "PSL_THREAD_CTX", ctx); ctx->userLabel = g_strdup(userLabel ? userLabel : "PSL_user"); if (!ctx->userLabel) { pslerr = PSL_ERR_MEM; goto error_cleanup; } gmainCtx = gmainCtx ? gmainCtx : g_main_context_default(); ctx->gmainCtx = g_main_context_ref(gmainCtx); PSL_LOG_DEBUG("%s (%s): PSL Thread Context created: ctx=%p", __func__, ctx->userLabel, ctx); *pThreadCtx = ctx; return 0; error_cleanup: PSL_ASSERT(pslerr); PSL_LOG_FATAL("%s (%s): ERROR: PslError=%d (%s)", __func__, PSL_LOG_MAKE_SAFE_STR(userLabel), (int)pslerr, PmSockErrStringFromError(pslerr)); if (ctx) { thread_context_destroy_internal(ctx); } return pslerr; }//PmSockThreadCtxNewFromGMain
/** ======================================================================== * ========================================================================= */ PslError psl_multi_fd_watch_add_or_update_fd(PslMultiFdWatchSource* const source, int const fd, GIOCondition const condition) { PslMultiFdDescriptor* desc; PSL_LOG_DEBUG("%s (watch=%p): fd=%d, GIOCondition=0x%lX", __func__, source, (int)fd, (unsigned long)condition); desc = (PslMultiFdDescriptor*) g_hash_table_lookup(source->descTable, GINT_TO_POINTER(fd)); /** * @note multi_fd_watch_prepare() takes care of adding/removing * our pollFd's from the source's poll list as needed */ if (desc) { PSL_LOG_DEBUGLOW( "%s (watch=%p): found desc=%p with fd=%d in descriptor table=%p", __func__, source, desc, (int)fd, source->descTable); desc->pollFd.events = condition; } else { /// create a new descriptor and add it to the poll set desc = g_new0(PslMultiFdDescriptor, 1); if (!desc) { PSL_LOG_FATAL("%s (watch=%p): ERROR: g_new0 failed", __func__, source); return PSL_ERR_MEM; } desc->pollFd.fd = fd; desc->pollFd.events = condition; g_hash_table_insert(source->descTable, GINT_TO_POINTER(desc->pollFd.fd), desc); PSL_LOG_DEBUGLOW( "%s (watch=%p): allocated desc=%p for fd=%d in descriptor table=%p", __func__, source, desc, (int)fd, source->descTable); } return 0; }
/** ======================================================================== * ========================================================================= */ 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; }