Arquivos
hhvm/hphp/runtime/ext/asio/reschedule_wait_handle.cpp
T
mwilliams 6c87ecb74e Remove dynamic_table_class.cpp
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.
2013-03-08 08:50:45 -08:00

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);
}
}
///////////////////////////////////////////////////////////////////////////////
}