예제 #1
0
void
Promise::PerformWorkerMicroTaskCheckpoint()
{
  MOZ_ASSERT(!NS_IsMainThread(), "Wrong thread!");

  CycleCollectedJSContext* context = CycleCollectedJSContext::Get();

  for (;;) {
    // For a normal microtask checkpoint, we try to use the debugger microtask
    // queue first. If the debugger queue is empty, we use the normal microtask
    // queue instead.
    std::queue<nsCOMPtr<nsIRunnable>>* microtaskQueue =
      &context->GetDebuggerPromiseMicroTaskQueue();

    if (microtaskQueue->empty()) {
      microtaskQueue = &context->GetPromiseMicroTaskQueue();
      if (microtaskQueue->empty()) {
        break;
      }
    }

    nsCOMPtr<nsIRunnable> runnable = microtaskQueue->front().forget();
    MOZ_ASSERT(runnable);

    // This function can re-enter, so we remove the element before calling.
    microtaskQueue->pop();
    nsresult rv = runnable->Run();
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return;
    }
    context->AfterProcessMicrotask();
  }
}
예제 #2
0
bool
Promise::PerformMicroTaskCheckpoint()
{
  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");

  CycleCollectedJSContext* context = CycleCollectedJSContext::Get();

  // On the main thread, we always use the main promise micro task queue.
  std::queue<nsCOMPtr<nsIRunnable>>& microtaskQueue =
    context->GetPromiseMicroTaskQueue();

  if (microtaskQueue.empty()) {
    return false;
  }

  AutoSlowOperation aso;

  do {
    nsCOMPtr<nsIRunnable> runnable = microtaskQueue.front().forget();
    MOZ_ASSERT(runnable);

    // This function can re-enter, so we remove the element before calling.
    microtaskQueue.pop();
    nsresult rv = runnable->Run();
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return false;
    }
    aso.CheckForInterrupt();
    context->AfterProcessMicrotask();
  } while (!microtaskQueue.empty());

  return true;
}