void c_ExternalThreadEventWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } // clean up once event is processed auto exit_guard = folly::makeGuard([&] { destroyEvent(); }); Cell result; try { m_event->unserialize(result); } catch (const Object& exception) { setException(exception.get()); return; } catch (...) { setException(AsioSession::Get()->getAbruptInterruptException().get()); throw; } assert(cellIsPlausible(result)); setResult(result); tvRefcountedDecRefCell(&result); }
void c_SleepWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } setResult(make_tv<KindOfNull>()); }
void c_ExternalThreadEventWaitHandle::enterContextImpl(context_idx_t ctx_idx) { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } setContextIdx(ctx_idx); registerToContext(); }
void c_SessionScopedWaitHandle::enterContextImpl(context_idx_t ctx_idx) { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } setContextIdx(ctx_idx); registerToContext(); }
void c_ExternalThreadEventWaitHandle::abandon(bool sweeping) { assert(getState() == STATE_WAITING); assert(hasExactlyOneRef() || sweeping); if (isInContext()) { unregisterFromContext(); } // clean up destroyEvent(sweeping); }
void c_SleepWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } auto const parentChain = getFirstParent(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); c_BlockableWaitHandle::UnblockChain(parentChain); }
void c_SleepWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnSleepSuccess())) { session->onSleepSuccess(this); } }
void c_ExternalThreadEventWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } // clean up once event is processed auto exit_guard = folly::makeGuard([&] { destroyEvent(); }); Cell result; try { m_event->unserialize(result); } catch (const Object& exception) { assert(exception->instanceof(SystemLib::s_ExceptionClass)); auto const parentChain = getFirstParent(); setState(STATE_FAILED); tvWriteObject(exception.get(), &m_resultOrException); c_BlockableWaitHandle::UnblockChain(parentChain); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnExternalThreadEventFailCallback())) { session->onExternalThreadEventFail(this, exception); } return; } catch (...) { auto const parentChain = getFirstParent(); setState(STATE_FAILED); tvWriteObject(AsioSession::Get()->getAbruptInterruptException(), &m_resultOrException); c_BlockableWaitHandle::UnblockChain(parentChain); throw; } assert(cellIsPlausible(result)); auto const parentChain = getFirstParent(); setState(STATE_SUCCEEDED); cellCopy(result, m_resultOrException); c_BlockableWaitHandle::UnblockChain(parentChain); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnExternalThreadEventSuccessCallback())) { session->onExternalThreadEventSuccess(this, tvAsCVarRef(&result)); } }
bool c_SleepWaitHandle::cancel(const Object& exception) { if (getState() != STATE_WAITING) { return false; // already finished } if (isInContext()) { unregisterFromContext(); } auto parentChain = getParentChain(); setState(STATE_FAILED); tvWriteObject(exception.get(), &m_resultOrException); parentChain.unblock(); // this is technically a lie, since sleep failed auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnSleepSuccess())) { session->onSleepSuccess(this); } return true; }
bool c_SleepWaitHandle::process() { if (getState() == STATE_FAILED) { // sleep handle was cancelled, everything is taken care of return false; } assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnSleepSuccess())) { session->onSleepSuccess(this); } return true; }
bool c_ExternalThreadEventWaitHandle::cancel(const Object& exception) { if (getState() != STATE_WAITING) { return false; // already finished } if (!m_event->cancel()) { return false; } // canceled; the processing thread will take care of cleanup if (isInContext()) { unregisterFromContext(); } // clean up once we finish canceling event auto exit_guard = folly::makeGuard([&] { // unregister Sweepable m_sweepable.unregister(); m_privData.reset(); // drop ownership by pending event (see initialize()) decRefObj(this); }); auto parentChain = getParentChain(); setState(STATE_FAILED); tvWriteObject(exception.get(), &m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnExternalThreadEventFail())) { session->onExternalThreadEventFail(this, exception, 0); } return true; }
void c_ExternalThreadEventWaitHandle::process() { assertx(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } // Store the finish time of the underlying IO operation // So we can pass it in the finish callbacks // clean up once event is processed auto exit_guard = folly::makeGuard([&] { destroyEvent(); }); Cell result; try { try { m_event->unserialize(result); } catch (ExtendedException& exception) { exception.recomputeBacktraceFromWH(this); throw exception; } } catch (const Object& exception) { assertx(exception->instanceof(SystemLib::s_ThrowableClass)); throwable_recompute_backtrace_from_wh(exception.get(), this); auto parentChain = getParentChain(); setState(STATE_FAILED); tvWriteObject(exception.get(), &m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnExternalThreadEventFail())) { session->onExternalThreadEventFail( this, exception, std::chrono::duration_cast<std::chrono::nanoseconds>( m_event->getFinishTime().time_since_epoch() ).count() ); } return; } catch (...) { auto parentChain = getParentChain(); setState(STATE_FAILED); tvWriteObject(AsioSession::Get()->getAbruptInterruptException(), &m_resultOrException); parentChain.unblock(); throw; } assertx(cellIsPlausible(result)); auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); cellCopy(result, m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnExternalThreadEventSuccess())) { session->onExternalThreadEventSuccess( this, tvAsCVarRef(&result), std::chrono::duration_cast<std::chrono::nanoseconds>( m_event->getFinishTime().time_since_epoch() ).count() ); } }