// throws on context depth level overflows and cross-context cycles void c_WaitableWaitHandle::join() { AsioSession* session = AsioSession::Get(); assert(!isFinished()); assert(!session->isInContext() || session->getCurrentContext()->isRunning()); if (UNLIKELY(session->hasOnJoinCallback())) { session->onJoin(this); } // enter new asio context and set up guard that will exit once we are done session->enterContext(); assert(session->isInContext()); assert(!session->getCurrentContext()->isRunning()); try { // import this wait handle to the newly created context // throws if cross-context cycle found enterContext(session->getCurrentContextIdx()); // run queues until we are finished session->getCurrentContext()->runUntil(this); } catch (const Object& exception) { // recover from PHP exceptions; HPHP internal exceptions are deliberately // ignored as there is no easy way to recover from them session->exitContext(); throw; } session->exitContext(); assert(isFinished()); }
// throws on context depth level overflows and cross-context cycles void c_WaitableWaitHandle::join() { JIT::EagerVMRegAnchor _; AsioSession* session = AsioSession::Get(); assert(!isFinished()); assert(!session->isInContext() || session->getCurrentContext()->isRunning()); if (UNLIKELY(session->hasOnJoinCallback())) { session->onJoin(this); } // enter new asio context and set up guard that will exit once we are done session->enterContext(); auto exit_guard = folly::makeGuard([&] { session->exitContext(); }); assert(session->isInContext()); assert(!session->getCurrentContext()->isRunning()); // import this wait handle to the newly created context // throws if cross-context cycle found enterContext(session->getCurrentContextIdx()); // run queues until we are finished session->getCurrentContext()->runUntil(this); assert(isFinished()); }
// throws on context depth level overflows and cross-context cycles void c_WaitableWaitHandle::join() { EagerVMRegAnchor _; auto const savedFP = vmfp(); assertx(!isFinished()); AsioSession* session = AsioSession::Get(); if (UNLIKELY(session->hasOnJoin())) { session->onJoin(this); } // enter new asio context and set up guard that will exit once we are done session->enterContext(savedFP); auto exit_guard = folly::makeGuard([&] { session->exitContext(); }); // import this wait handle to the newly created context // throws if cross-context cycle found asio::enter_context(this, session->getCurrentContextIdx()); // run queues until we are finished session->getCurrentContext()->runUntil(this); assertx(isFinished()); }