Exemple #1
0
void AsioBlockableChain::unblock() {
  auto cur = m_firstParent;
  while (cur) {
    auto const next = cur->getNextParent();

    // May free cur.
    switch (cur->getKind()) {
      case Kind::AsyncFunctionWaitHandleNode:
        getAsyncFunctionWaitHandleNode(cur)->onUnblocked();
        break;
      case Kind::AsyncGeneratorWaitHandle:
        getAsyncGeneratorWaitHandle(cur)->onUnblocked();
        break;
      case Kind::AwaitAllWaitHandle:
        getAwaitAllWaitHandle(cur)->onUnblocked();
        break;
      case Kind::ConditionWaitHandle:
        getConditionWaitHandle(cur)->onUnblocked();
        break;
      case Kind::GenArrayWaitHandle:
        getGenArrayWaitHandle(cur)->onUnblocked();
        break;
      case Kind::GenMapWaitHandle:
        getGenMapWaitHandle(cur)->onUnblocked();
        break;
      case Kind::GenVectorWaitHandle:
        getGenVectorWaitHandle(cur)->onUnblocked();
        break;
    }

    cur = next;
  }
}
Exemple #2
0
void AsioBlockableChain::exitContext(context_idx_t ctx_idx) {
  for (auto cur = m_firstParent; cur; cur = cur->getNextParent()) {
    switch (cur->getKind()) {
      case Kind::AsyncFunctionWaitHandleNode:
        exitContextImpl(getAsyncFunctionWaitHandleNode(cur), ctx_idx);
        break;
      case Kind::AsyncGeneratorWaitHandle:
        exitContextImpl(getAsyncGeneratorWaitHandle(cur), ctx_idx);
        break;
      case Kind::AwaitAllWaitHandle:
        exitContextImpl(getAwaitAllWaitHandle(cur), ctx_idx);
        break;
      case Kind::ConditionWaitHandle:
        exitContextImpl(getConditionWaitHandle(cur), ctx_idx);
        break;
      case Kind::GenArrayWaitHandle:
        exitContextImpl(getGenArrayWaitHandle(cur), ctx_idx);
        break;
      case Kind::GenMapWaitHandle:
        exitContextImpl(getGenMapWaitHandle(cur), ctx_idx);
        break;
      case Kind::GenVectorWaitHandle:
        exitContextImpl(getGenVectorWaitHandle(cur), ctx_idx);
        break;
    }
  }
}
Array c_WaitableWaitHandle::t_getdependencystack() {
  Array result = Array::Create();
  if (isFinished()) return result;
  hphp_hash_set<int64_t> visited;
  auto wait_handle = this;
  while (wait_handle != nullptr) {
    result.append(wait_handle);
    visited.insert(wait_handle->t_getid());
    auto context_idx = wait_handle->getContextIdx();

    // 1. find parent in the same context
    auto p = wait_handle->getFirstParent();
    while (p) {
      if ((p->getContextIdx() == context_idx) &&
          visited.find(p->t_getid()) == visited.end()) {
        wait_handle = p;
        break;
      }
      p = p->getNextParent();
    }
    if (p) continue;

    // 2. cross the context boundary
    result.append(null_object);
    wait_handle = (context_idx > 1)
      ? AsioSession::Get()->getContext(context_idx - 1)->getCurrent()
      : nullptr;
  }
  return result;
}
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 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);
  }
}
Exemple #5
0
c_WaitableWaitHandle*
AsioBlockableChain::firstInContext(context_idx_t ctx_idx) {
  for (auto cur = m_firstParent; cur; cur = cur->getNextParent()) {
    auto const wh = cur->getWaitHandle();
    if (!wh->isFinished() && wh->getContextIdx() == ctx_idx) {
      return wh;
    }
  }
  return nullptr;
}
Exemple #6
0
Array AsioBlockableChain::toArray() {
  Array result = Array::Create();
  for (auto cur = m_firstParent; cur; cur = cur->getNextParent()) {
    auto const wh = cur->getWaitHandle();
    if (!wh->isFinished()) {
      result.append(wh);
    }
  }
  return result;
}
void AsioBlockableChain::exitContext(context_idx_t ctx_idx) {
  for (auto cur = m_firstParent; cur; cur = cur->getNextParent()) {
    switch (cur->getKind()) {
      case AsioBlockable::Kind::BlockableWaitHandle:
        cur->getBlockableWaitHandle()->exitContextBlocked(ctx_idx);
        break;
      case AsioBlockable::Kind::ConditionWaitHandle:
        cur->getConditionWaitHandle()->exitContextBlocked(ctx_idx);
        break;
    }
  }
}
c_BlockableWaitHandle*
AsioBlockableChain::firstInContext(context_idx_t ctx_idx) {
  for (auto cur = m_firstParent; cur; cur = cur->getNextParent()) {
    switch (cur->getKind()) {
      case AsioBlockable::Kind::BlockableWaitHandle: {
        auto const wh = cur->getBlockableWaitHandle();
        if (wh->getContextIdx() == ctx_idx) return wh;
        break;
      }
      case AsioBlockable::Kind::ConditionWaitHandle:
        // ConditionWaitHandle not supported in legacy dependency stack.
        break;
    }
  }
  return nullptr;
}
Array AsioBlockableChain::toArray() {
  Array result = Array::Create();

  for (auto cur = m_firstParent; cur; cur = cur->getNextParent()) {
    switch (cur->getKind()) {
      case AsioBlockable::Kind::BlockableWaitHandle:
        result.append(cur->getBlockableWaitHandle());
        break;
      case AsioBlockable::Kind::ConditionWaitHandle:
        result.append(cur->getConditionWaitHandle());
        break;
    }
  }

  return result;
}
void c_AsyncFunctionWaitHandle::exitContext(context_idx_t ctx_idx) {
  assert(AsioSession::Get()->getContext(ctx_idx));

  // stop before corrupting unioned data
  if (isFinished()) {
    decRefObj(this);
    return;
  }

  // not in a context being exited
  assert(getContextIdx() <= ctx_idx);
  if (getContextIdx() != ctx_idx) {
    decRefObj(this);
    return;
  }

  switch (getState()) {
    case STATE_BLOCKED:
      // we were already ran due to duplicit scheduling; the context will be
      // updated thru exitContext() call on the non-blocked wait handle we
      // recursively depend on
      decRefObj(this);
      break;

    case STATE_SCHEDULED:
      // Recursively move all wait handles blocked by us.
      for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) {
        pwh->exitContextBlocked(ctx_idx);
      }

      // Move us to the parent context.
      setContextIdx(getContextIdx() - 1);

      // Reschedule if still in a context.
      if (isInContext()) {
        getContext()->schedule(this);
      } else {
        decRefObj(this);
      }

      break;

    default:
      assert(false);
  }
}
void c_ExternalThreadEventWaitHandle::exitContext(context_idx_t ctx_idx) {
  assert(AsioSession::Get()->getContext(ctx_idx));
  assert(getContextIdx() == ctx_idx);
  assert(getState() == STATE_WAITING);

  // Move us to the parent context.
  setContextIdx(getContextIdx() - 1);

  // Re-register if still in a context.
  if (isInContext()) {
    registerToContext();
  }

  // Recursively move all wait handles blocked by us.
  for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) {
    pwh->exitContextBlocked(ctx_idx);
  }
}
void AsioBlockableChain::unblock() {
  auto cur = m_firstParent;
  while (cur) {
    auto const next = cur->getNextParent();

    // May free cur.
    switch (cur->getKind()) {
      case AsioBlockable::Kind::BlockableWaitHandle:
        dispatchUnblock(cur->getBlockableWaitHandle());
        break;
      case AsioBlockable::Kind::ConditionWaitHandle:
        cur->getConditionWaitHandle()->onUnblocked();
        break;
    }

    cur = next;
  }
}
void c_BlockableWaitHandle::exitContextBlocked(context_idx_t ctx_idx) {
  assert(getState() == STATE_BLOCKED);
  assert(AsioSession::Get()->getContext(ctx_idx));

  // not in a context being exited
  assert(getContextIdx() <= ctx_idx);
  if (getContextIdx() != ctx_idx) {
    return;
  }

  // move us to the parent context
  setContextIdx(getContextIdx() - 1);

  // recursively move all wait handles blocked by us
  for (auto pwh = getFirstParent(); pwh; pwh = pwh->getNextParent()) {
    pwh->exitContextBlocked(ctx_idx);
  }
}
Exemple #14
0
Array c_WaitableWaitHandle::t_getdependencystack() {
  Array result = Array::Create();
  if (isFinished()) return result;
  hphp_hash_set<int64_t> visited;
  auto wait_handle = this;
  auto session = AsioSession::Get();
  while (wait_handle != nullptr) {
    result.append(wait_handle);
    visited.insert(wait_handle->t_getid());
    auto context_idx = wait_handle->getContextIdx();

    // 1. find parent in the same context
    auto p = wait_handle->getFirstParent();
    while (p) {
      if ((p->getContextIdx() == context_idx) &&
          visited.find(p->t_getid()) == visited.end()) {
        wait_handle = p;
        break;
      }
      p = p->getNextParent();
    }
    if (p) continue;

    // 2. cross the context boundary
    auto context = session->getContext(context_idx);
    if (!context) {
      break;
    }
    wait_handle = c_ResumableWaitHandle::getRunning(context->getSavedFP());
    auto target_context_idx = wait_handle ? wait_handle->getContextIdx() : 0;
    while (context_idx > target_context_idx) {
      --context_idx;
      result.append(null_object);
    }
  }
  return result;
}
void Comparator::check( spec_reader::Specification& spec, file_reader::FileReader& file, report_generator::Report& report )
{
	ShPtrSpecNode node = spec.getFirstNode();
	ShPtrElement element( new basic_element::Element( node ) );

	element_checker::Checker checker;
	size_t size = checker.getSize( element );

	char buffer1[ size ];
	if( ! file.readData( buffer1, size ) )
		throw std::runtime_error( "[comparator] End of file, cannot read data" );
	element->set( buffer1, size );

	checker.check( element );
	LOG_TRACE( "[comparator] checked:" << element->_id << " = " << element->_dispValue << " (" << statusMap.at( element->_status ) << ")" );

	std::shared_ptr< basic_element::Element > parent;
	parent = getNextParent( element, node );
	report.add( element );
	report.print( element );

	while( ( node = element->next() ) != nullptr )
	{
		// LOG_FATAL( node->getId() );
		ShPtrElement previous = element;
		
		if( skipElementCheck( previous ) )
		{
			LOG_TRACE( "[comparator] Go back in file (" << size << " bytes)" );
			file.goBack( size );
			previous = element->getPrevious();
		}

		element = std::make_shared< basic_element::Element >( node, previous, parent );
		size = checker.getSize( element );

		if( size > ( file.getLength() - file.getPosition() ) && ( isInUnorderedGroup( element ) || element->_isOptional ) )
		{
			LOG_TRACE( "[comparator] Critical remaining file data size: " << size << "/" << file.getLength() - file.getPosition() );
			size = file.getLength() - file.getPosition();
			if( size == 0 )
				break;
		}

		char buffer[ size ];
		if( ! file.readData( buffer, size ) )
			throw std::runtime_error( "[comparator] End of file, cannot read data" );
		element->set( buffer, size );

		checker.check( element );
		LOG_TRACE( "[comparator] checked: " << element->_id << " = " << element->_dispValue << " (" << statusMap.at( element->_status ) << ") @ " << element << " << Previous: " << previous << " << Parent: " );
		// LOG_COLOR( common::details::kColorMagenta, "[comparator] checked: " << element->_id << " = " << element->_dispValue << " (" << statusMap.at( element->_status ) << ") @ " << element << " << Previous: " << previous << " << Parent: " << parent << std::endl );

		// if( ! skipElementCheck( element ) && parent != nullptr )
		// 	parent->_childrenSize += element->_size;
		updateParentSize( element );

		checkGroupSize( element, file );

		report.add( element );
		report.update( parent );
		parent = getNextParent( element, node );

		if( parent != nullptr )
		{
			LOG_TRACE( "[comparator] next parent: id = " << parent->_id );
		}
		else
			LOG_TRACE( "[comparator] next parent: null" );
		report.print( element );
	}

	if( ! file.isEndOfFile() )
		LOG_WARNING( "Did not reach the end of file, remaining " << file.getLength() - file.getPosition() << " bytes." );
}