コード例 #1
0
ファイル: asio-context.cpp プロジェクト: 292388900/hhvm
c_WaitableWaitHandle* AsioContext::getBlamedWaitHandle() {
  // first let's try to find wait handle, responsible for wakeup
  auto session = AsioSession::Get();
  auto ete_queue = session->getExternalThreadEventQueue();

  c_ExternalThreadEventWaitHandle* ewh = ete_queue->lastReceived();
  if (ewh != nullptr &&
      ewh->getContextIdx() == session->getCurrentContextIdx()) {
    return ewh;
  }

  // may return cancelled wait handle, which no longer has contextIdx
  c_SleepWaitHandle* swh = session->nextSleepEvent();
  if (swh != nullptr && !swh->isFinished() &&
      swh->getContextIdx() == session->getCurrentContextIdx() &&
      swh->getWakeTime() <= AsioSession::TimePoint::clock::now()) {
    return swh;
  }

  // not found? let's find a wait handle from current context to blame
  if (!m_externalThreadEvents.empty()) {
    return m_externalThreadEvents[0];
  }

  if (!m_sleepEvents.empty()) {
    return m_sleepEvents[0];
  }

  return nullptr;
}
コード例 #2
0
ファイル: asio-session.cpp プロジェクト: sskblr/hhvm
void AsioSession::enterContext(ActRec* savedFP) {
    if (UNLIKELY(getCurrentContextIdx() >= MAX_CONTEXT_DEPTH)) {
        SystemLib::throwInvalidOperationExceptionObject(
            "Unable to enter asio context: too many contexts open");
    }

    m_contexts.push_back(req::make_raw<AsioContext>(savedFP));

    assert(static_cast<context_idx_t>(m_contexts.size()) == m_contexts.size());
    assert(isInContext());
}
コード例 #3
0
Object c_SetResultToRefWaitHandle::ti_create(CObjRef wait_handle, VRefParam ref) {
  TypedValue* var_or_cell = ref->asTypedValue();
  if (wait_handle.isNull()) {
    tvSetNull(*var_or_cell);
    return wait_handle;
  }

  if (!wait_handle.get()->getAttribute(ObjectData::IsWaitHandle)) {
    Object e(SystemLib::AllocInvalidArgumentExceptionObject(
        "Expected wait_handle to be an instance of WaitHandle or null"));
    throw e;
  }

  auto wh = static_cast<c_WaitHandle*>(wait_handle.get());

  // succeeded? set result to ref and give back succeeded wait handle
  if (wh->isSucceeded()) {
    tvSet(wh->getResult(), *var_or_cell);
    return wh;
  }

  // failed? reset ref and give back failed wait handle
  if (wh->isFailed()) {
    tvSetNull(*var_or_cell);
    return wh;
  }

  // it's still running so it must be WaitableWaitHandle
  auto child = static_cast<c_WaitableWaitHandle*>(wh);

  // import child into the current context, detect cross-context cycles
  auto session = AsioSession::Get();
  if (session->isInContext()) {
    child->enterContext(session->getCurrentContextIdx());
  }

  // make sure the reference is properly boxed so that we can store cell pointer
  if (UNLIKELY(var_or_cell->m_type != KindOfRef)) {
    tvBox(var_or_cell);
  }

  p_SetResultToRefWaitHandle my_wh = NEWOBJ(c_SetResultToRefWaitHandle)();
  my_wh->initialize(child, var_or_cell->m_data.pref);

  if (UNLIKELY(session->hasOnSetResultToRefCreateCallback())) {
    session->onSetResultToRefCreate(my_wh.get(), child);
  }

  return my_wh;
}
コード例 #4
0
ファイル: asio_session.cpp プロジェクト: Fininvest/hhvm
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());
}
コード例 #5
0
Object f_asio_get_running_in_context(int ctx_idx) {
  auto session = AsioSession::Get();

  if (ctx_idx <= 0) {
    Object e(SystemLib::AllocInvalidArgumentExceptionObject(
      "Expected ctx_idx to be a positive integer"));
    throw e;
  }
  if (ctx_idx > session->getCurrentContextIdx()) {
    Object e(SystemLib::AllocInvalidArgumentExceptionObject(
      "Expected ctx_idx to be less than or equal to the current context index"));
    throw e;
  }

  assert(session->getContext(ctx_idx));
  assert(session->getContext(ctx_idx)->isRunning());
  return session->getContext(ctx_idx)->getCurrent();
}
コード例 #6
0
void c_ExternalThreadEventWaitHandle::initialize(
  AsioExternalThreadEvent* event,
  ObjectData* priv_data
) {
  auto const session = AsioSession::Get();
  setState(STATE_WAITING);
  setContextIdx(session->getCurrentContextIdx());
  m_event = event;
  m_privData = priv_data;

  if (isInContext()) {
    registerToContext();
  }

  if (UNLIKELY(session->hasOnExternalThreadEventCreate())) {
    session->onExternalThreadEventCreate(this);
  }
}
コード例 #7
0
ファイル: sleep-wait-handle.cpp プロジェクト: 191919/hhvm
void c_SleepWaitHandle::initialize(int64_t usecs) {
  auto const session = AsioSession::Get();
  setState(STATE_WAITING);
  setContextIdx(session->getCurrentContextIdx());
  m_waketime =
    AsioSession::TimePoint::clock::now() +
    std::chrono::microseconds(usecs);

  incRefCount();

  session->enqueueSleepEvent(this);

  if (isInContext()) {
    registerToContext();
  }

  if (UNLIKELY(session->hasOnSleepCreate())) {
    session->onSleepCreate(this);
  }
}