void c_RescheduleWaitHandle::exitContext(context_idx_t ctx_idx) { assert(AsioSession::Get()->getContext(ctx_idx)); // stop before corrupting unioned data if (isFinished()) { return; } // not in a context being exited assert(getContextIdx() <= ctx_idx); if (getContextIdx() != ctx_idx) { return; } if (UNLIKELY(getState() != STATE_SCHEDULED)) { throw FatalErrorException( "Invariant violation: encountered unexpected state"); } // move us to the parent context setContextIdx(getContextIdx() - 1); // reschedule if still in a context if (isInContext()) { getContext()->schedule(this, m_queue, m_priority); } // recursively move all wait handles blocked by us for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) { pwh->exitContextBlocked(ctx_idx); } }
void c_AsyncFunctionWaitHandle::exitContext(context_idx_t ctx_idx) { assert(AsioSession::Get()->getContext(ctx_idx)); // stop before corrupting unioned data if (isFinished()) { decRefObj(this); return; } // not in a context being exited assert(getContextIdx() <= ctx_idx); if (getContextIdx() != ctx_idx) { decRefObj(this); return; } switch (getState()) { case STATE_BLOCKED: // we were already ran due to duplicit scheduling; the context will be // updated thru exitContext() call on the non-blocked wait handle we // recursively depend on decRefObj(this); break; case STATE_SCHEDULED: // Recursively move all wait handles blocked by us. for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) { pwh->exitContextBlocked(ctx_idx); } // Move us to the parent context. setContextIdx(getContextIdx() - 1); // Reschedule if still in a context. if (isInContext()) { getContext()->schedule(this); } else { decRefObj(this); } break; default: assert(false); } }
void c_ExternalThreadEventWaitHandle::exitContext(context_idx_t ctx_idx) { assert(AsioSession::Get()->getContext(ctx_idx)); assert(getContextIdx() == ctx_idx); assert(getState() == STATE_WAITING); // Move us to the parent context. setContextIdx(getContextIdx() - 1); // Re-register if still in a context. if (isInContext()) { registerToContext(); } // Recursively move all wait handles blocked by us. for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) { pwh->exitContextBlocked(ctx_idx); } }
void c_BlockableWaitHandle::exitContextBlocked(context_idx_t ctx_idx) { assert(getState() == STATE_BLOCKED); assert(AsioSession::Get()->getContext(ctx_idx)); // not in a context being exited assert(getContextIdx() <= ctx_idx); if (getContextIdx() != ctx_idx) { return; } // move us to the parent context setContextIdx(getContextIdx() - 1); // recursively move all wait handles blocked by us for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) { pwh->exitContextBlocked(ctx_idx); } }