| Index: components/scheduler/promises/promise_executor.cc
|
| diff --git a/components/scheduler/promises/promise_executor.cc b/components/scheduler/promises/promise_executor.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..be3a60ddad3efb69c664eddb74c229f6f3a81d67
|
| --- /dev/null
|
| +++ b/components/scheduler/promises/promise_executor.cc
|
| @@ -0,0 +1,86 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/scheduler/promises/promise_executor.h"
|
| +
|
| +namespace promise {
|
| +namespace internal {
|
| +
|
| +PromiseExecutor::PromiseExecutor() : cursor_(nullptr) {}
|
| +
|
| +PromiseExecutor::~PromiseExecutor(){};
|
| +
|
| +void PromiseExecutor::StartResolveInternal(PromiseBase* promise) {
|
| + if (promise->state() == PromiseBase::State::NEW ||
|
| + promise->state() == PromiseBase::State::CANCELLED) {
|
| + promise->set_state(PromiseBase::State::PENDING);
|
| + }
|
| +
|
| + promise->SetThisAndPrerequisitesAsShouldRun(this, true);
|
| +}
|
| +
|
| +PromiseBase* PromiseExecutor::GetNextReadyPromise() {
|
| + if (!eager_ready_set_.empty()) {
|
| + PromiseBase* ready_promise = *eager_ready_set_.begin();
|
| + eager_ready_set_.erase(ready_promise);
|
| + return ready_promise;
|
| + }
|
| + if (!lazy_ready_set_.empty()) {
|
| + PromiseBase* ready_promise = *lazy_ready_set_.begin();
|
| + lazy_ready_set_.erase(ready_promise);
|
| + return ready_promise;
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +bool PromiseExecutor::ResolveOnePromise() {
|
| + PromiseBase* ready_promise = GetNextReadyPromise();
|
| + if (!ready_promise)
|
| + return false;
|
| +
|
| + ResolvePromise(ready_promise);
|
| + return true;
|
| +}
|
| +
|
| +void PromiseExecutor::ResolvePromise(PromiseBase* promise) {
|
| + DCHECK(promise->state() != PromiseBase::State::RESOLVED);
|
| + DCHECK(promise->AllPrerequisitesSatisfied());
|
| +
|
| + if (promise->state() == PromiseBase::State::PARTIALLY_RESOLVED) {
|
| + promise->MarkAsResolved();
|
| + } else {
|
| + promise->ExecutorDrivenResolve();
|
| + }
|
| +}
|
| +
|
| +void PromiseExecutor::RunUntilIdle() {
|
| + while (ResolveOnePromise()) {
|
| + }
|
| +}
|
| +
|
| +bool PromiseExecutor::OnPromiseResolved(PromiseBase* promise) {
|
| + bool new_work_to_do = false;
|
| + for (PromiseBase* dependee : promise->dependants()) {
|
| + if (dependee->AllPrerequisitesSatisfied()) {
|
| + if (!dependee->can_run_now())
|
| + new_work_to_do = true;
|
| + dependee->SchedulePromiseForResolve();
|
| + }
|
| + }
|
| + return new_work_to_do;
|
| +}
|
| +
|
| +bool PromiseExecutor::OnPromiseRejected(PromiseBase* promise) {
|
| + bool new_work_to_do = false;
|
| + for (PromiseBase* dependee : promise->dependants()) {
|
| + dependee->set_state(PromiseBase::State::DEPENDENCY_REJECTED);
|
| + if (!dependee->can_run_now())
|
| + new_work_to_do = true;
|
| + dependee->SchedulePromiseForResolve();
|
| + }
|
| + return new_work_to_do;
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace promise
|
|
|