6c87ecb74e
We only used it to get the values of certain class constants, and to define the ObjectStaticCallbacks for every class. We can put the class constants directly into the class_map (we should have done that before for perf reasons), and then the only remaining use of ObjectStaticCallbacks is to proxy the Class* for each builtin class. So just use the Class* directly. Once this is in, Im just a small step away from eliminating make -C hphp/system - so Im leaving a lot of dead code here. Its going to be easier to delete it en masse, rather than try to pick and chose now.
143 linhas
4.4 KiB
C++
143 linhas
4.4 KiB
C++
/*
|
|
+----------------------------------------------------------------------+
|
|
| HipHop for PHP |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2010- 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 <runtime/ext/ext_asio.h>
|
|
#include <runtime/ext/asio/asio_context.h>
|
|
#include <runtime/ext/asio/asio_session.h>
|
|
#include <system/lib/systemlib.h>
|
|
|
|
namespace HPHP {
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace {
|
|
StaticString s_reschedule("<reschedule>");
|
|
}
|
|
|
|
const int q_RescheduleWaitHandle$$QUEUE_DEFAULT = AsioContext::QUEUE_DEFAULT;
|
|
const int q_RescheduleWaitHandle$$QUEUE_NO_PENDING_IO = AsioContext::QUEUE_NO_PENDING_IO;
|
|
|
|
c_RescheduleWaitHandle::c_RescheduleWaitHandle(VM::Class *cb)
|
|
: c_WaitableWaitHandle(cb) {
|
|
}
|
|
|
|
c_RescheduleWaitHandle::~c_RescheduleWaitHandle() {
|
|
}
|
|
|
|
void c_RescheduleWaitHandle::t___construct() {
|
|
Object e(SystemLib::AllocInvalidOperationExceptionObject(
|
|
"Use RescheduleWaitHandle::create() instead of constructor"));
|
|
throw e;
|
|
}
|
|
|
|
Object c_RescheduleWaitHandle::ti_create(const char* cls, int queue, int priority) {
|
|
if (UNLIKELY(
|
|
queue != q_RescheduleWaitHandle$$QUEUE_DEFAULT &&
|
|
queue != q_RescheduleWaitHandle$$QUEUE_NO_PENDING_IO)) {
|
|
Object e(SystemLib::AllocInvalidArgumentExceptionObject(
|
|
"Expected queue to be a value defined by one of the QUEUE_ constants"));
|
|
throw e;
|
|
}
|
|
|
|
if (UNLIKELY(priority < 0)) {
|
|
Object e(SystemLib::AllocInvalidArgumentExceptionObject(
|
|
"Expected priority to be a non-negative integer"));
|
|
throw e;
|
|
}
|
|
|
|
c_RescheduleWaitHandle* wh = NEWOBJ(c_RescheduleWaitHandle);
|
|
wh->initialize(static_cast<uint32_t>(queue), static_cast<uint32_t>(priority));
|
|
return wh;
|
|
}
|
|
|
|
void c_RescheduleWaitHandle::initialize(uint32_t queue, uint32_t priority) {
|
|
m_queue = queue;
|
|
m_priority = priority;
|
|
|
|
setState(STATE_SCHEDULED);
|
|
if (isInContext()) {
|
|
getContext()->schedule(this, m_queue, m_priority);
|
|
}
|
|
}
|
|
|
|
void c_RescheduleWaitHandle::run() {
|
|
// may happen if scheduled in multiple contexts
|
|
if (getState() != STATE_SCHEDULED) {
|
|
return;
|
|
}
|
|
|
|
setResult(init_null_variant.asTypedValue());
|
|
}
|
|
|
|
String c_RescheduleWaitHandle::getName() {
|
|
return s_reschedule;
|
|
}
|
|
|
|
void c_RescheduleWaitHandle::enterContext(context_idx_t ctx_idx) {
|
|
assert(AsioSession::Get()->getContext(ctx_idx));
|
|
|
|
// stop before corrupting unioned data
|
|
if (isFinished()) {
|
|
return;
|
|
}
|
|
|
|
// already in the more specific context?
|
|
if (LIKELY(getContextIdx() >= ctx_idx)) {
|
|
return;
|
|
}
|
|
|
|
assert(getState() == STATE_SCHEDULED);
|
|
|
|
setContextIdx(ctx_idx);
|
|
getContext()->schedule(this, m_queue, m_priority);
|
|
}
|
|
|
|
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 new 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);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
}
|