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 |