Arquivos
hhvm/hphp/runtime/ext/asio/asio_session.cpp
T
Jan Oravec 797a6822d0 Move external thread event queue logic from AsioSession to AsioExternalThreadEventQueue
External thread event queueing logic is big enough that it deserves its
own class. Move the code and rename members to better reflect the
underlying operations. Implementation is otherwise unchanged.
2013-06-17 13:02:11 -07:00

175 linhas
6.1 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/runtime/ext/asio/asio_session.h"
#include "hphp/runtime/ext/ext_asio.h"
#include "hphp/system/systemlib.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
IMPLEMENT_THREAD_LOCAL_PROXY(AsioSession, false, AsioSession::s_current);
namespace {
const context_idx_t MAX_CONTEXT_DEPTH = std::numeric_limits<context_idx_t>::max();
}
void AsioSession::Init() {
s_current.set(new AsioSession());
}
AsioSession::AsioSession()
: m_contexts(), m_externalThreadEventQueue() {
}
void AsioSession::enterContext() {
assert(!isInContext() || getCurrentContext()->isRunning());
if (UNLIKELY(getCurrentContextIdx() >= MAX_CONTEXT_DEPTH)) {
Object e(SystemLib::AllocInvalidOperationExceptionObject(
"Unable to enter asio context: too many contexts open"));
throw e;
}
m_contexts.push_back(new AsioContext());
assert(static_cast<context_idx_t>(m_contexts.size()) == m_contexts.size());
assert(isInContext());
assert(!getCurrentContext()->isRunning());
}
void AsioSession::exitContext() {
assert(isInContext());
assert(!getCurrentContext()->isRunning());
m_contexts.back()->exit(m_contexts.size());
delete m_contexts.back();
m_contexts.pop_back();
assert(!isInContext() || getCurrentContext()->isRunning());
}
uint16_t AsioSession::getCurrentWaitHandleDepth() {
assert(!isInContext() || getCurrentContext()->isRunning());
return isInContext() ? getCurrentWaitHandle()->getDepth() : 0;
}
void AsioSession::initAbruptInterruptException() {
assert(!hasAbruptInterruptException());
m_abruptInterruptException = SystemLib::AllocInvalidOperationExceptionObject(
"The request was abruptly interrupted.");
}
void AsioSession::onFailed(CObjRef exception) {
if (m_onFailedCallback.get()) {
try {
vm_call_user_func(m_onFailedCallback, Array::Create(exception));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by onFailed callback");
}
}
}
void AsioSession::onContinuationCreate(c_ContinuationWaitHandle* cont) {
assert(m_onContinuationCreateCallback.get());
try {
vm_call_user_func(
m_onContinuationCreateCallback,
Array::Create(cont));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by ContinuationWaitHandle::onCreate callback");
}
}
void AsioSession::onContinuationYield(c_ContinuationWaitHandle* cont, c_WaitHandle* child) {
assert(m_onContinuationYieldCallback.get());
try {
vm_call_user_func(
m_onContinuationYieldCallback,
CREATE_VECTOR2(cont, child));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by ContinuationWaitHandle::onYield callback");
}
}
void AsioSession::onContinuationSuccess(c_ContinuationWaitHandle* cont, CVarRef result) {
assert(m_onContinuationSuccessCallback.get());
try {
vm_call_user_func(
m_onContinuationSuccessCallback,
CREATE_VECTOR2(cont, result));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by ContinuationWaitHandle::onSuccess callback");
}
}
void AsioSession::onContinuationFail(c_ContinuationWaitHandle* cont, CObjRef exception) {
assert(m_onContinuationFailCallback.get());
try {
vm_call_user_func(
m_onContinuationFailCallback,
CREATE_VECTOR2(cont, exception));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by ContinuationWaitHandle::onFail callback");
}
}
void AsioSession::onJoin(c_WaitHandle* wait_handle) {
assert(m_onJoinCallback.get());
try {
vm_call_user_func(m_onJoinCallback, Array::Create(wait_handle));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by WaitHandle::onJoin callback");
}
}
void AsioSession::onGenArrayCreate(c_GenArrayWaitHandle* wait_handle, CVarRef dependencies) {
assert(m_onGenArrayCreateCallback.get());
try {
vm_call_user_func(
m_onGenArrayCreateCallback,
CREATE_VECTOR2(wait_handle, dependencies));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by GenArrayWaitHandle::onCreate callback");
}
}
void AsioSession::onGenVectorCreate(c_GenVectorWaitHandle* wait_handle, CVarRef dependencies) {
assert(m_onGenVectorCreateCallback.get());
try {
vm_call_user_func(
m_onGenVectorCreateCallback,
CREATE_VECTOR2(wait_handle, dependencies));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by GenVectorWaitHandle::onCreate callback");
}
}
void AsioSession::onSetResultToRefCreate(c_SetResultToRefWaitHandle* wait_handle, CObjRef child) {
assert(m_onSetResultToRefCreateCallback.get());
try {
vm_call_user_func(
m_onSetResultToRefCreateCallback,
CREATE_VECTOR2(wait_handle, child));
} catch (const Object& callback_exception) {
raise_warning("[asio] Ignoring exception thrown by SetResultToRefWaitHandle::onCreate callback");
}
}
///////////////////////////////////////////////////////////////////////////////
}