summaryrefslogtreecommitdiff
path: root/deps/v8/src/libplatform/default-foreground-task-runner.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/libplatform/default-foreground-task-runner.cc')
-rw-r--r--deps/v8/src/libplatform/default-foreground-task-runner.cc115
1 files changed, 115 insertions, 0 deletions
diff --git a/deps/v8/src/libplatform/default-foreground-task-runner.cc b/deps/v8/src/libplatform/default-foreground-task-runner.cc
new file mode 100644
index 0000000000..c9cb5fa4d7
--- /dev/null
+++ b/deps/v8/src/libplatform/default-foreground-task-runner.cc
@@ -0,0 +1,115 @@
+// Copyright 2017 the V8 project 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 "src/libplatform/default-foreground-task-runner.h"
+
+#include "src/base/platform/mutex.h"
+#include "src/libplatform/default-platform.h"
+
+namespace v8 {
+namespace platform {
+
+DefaultForegroundTaskRunner::DefaultForegroundTaskRunner(
+ IdleTaskSupport idle_task_support, TimeFunction time_function)
+ : event_loop_control_(0),
+ idle_task_support_(idle_task_support),
+ time_function_(time_function) {}
+
+void DefaultForegroundTaskRunner::Terminate() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ terminated_ = true;
+
+ // Drain the task queues.
+ while (!task_queue_.empty()) task_queue_.pop();
+ while (!delayed_task_queue_.empty()) delayed_task_queue_.pop();
+ while (!idle_task_queue_.empty()) idle_task_queue_.pop();
+}
+
+void DefaultForegroundTaskRunner::PostTaskLocked(
+ std::unique_ptr<Task> task, const base::LockGuard<base::Mutex>& guard) {
+ if (terminated_) return;
+ task_queue_.push(std::move(task));
+ event_loop_control_.Signal();
+}
+
+void DefaultForegroundTaskRunner::PostTask(std::unique_ptr<Task> task) {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ PostTaskLocked(std::move(task), guard);
+}
+
+double DefaultForegroundTaskRunner::MonotonicallyIncreasingTime() {
+ return time_function_();
+}
+
+void DefaultForegroundTaskRunner::PostDelayedTask(std::unique_ptr<Task> task,
+ double delay_in_seconds) {
+ DCHECK_GE(delay_in_seconds, 0.0);
+ base::LockGuard<base::Mutex> guard(&lock_);
+ if (terminated_) return;
+ double deadline = MonotonicallyIncreasingTime() + delay_in_seconds;
+ delayed_task_queue_.push(std::make_pair(deadline, std::move(task)));
+}
+
+void DefaultForegroundTaskRunner::PostIdleTask(std::unique_ptr<IdleTask> task) {
+ CHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
+ base::LockGuard<base::Mutex> guard(&lock_);
+ if (terminated_) return;
+ idle_task_queue_.push(std::move(task));
+}
+
+bool DefaultForegroundTaskRunner::IdleTasksEnabled() {
+ return idle_task_support_ == IdleTaskSupport::kEnabled;
+}
+
+std::unique_ptr<Task> DefaultForegroundTaskRunner::PopTaskFromQueue() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ // Move delayed tasks that hit their deadline to the main queue.
+ std::unique_ptr<Task> task = PopTaskFromDelayedQueueLocked(guard);
+ while (task) {
+ PostTaskLocked(std::move(task), guard);
+ task = PopTaskFromDelayedQueueLocked(guard);
+ }
+
+ if (task_queue_.empty()) return {};
+
+ task = std::move(task_queue_.front());
+ task_queue_.pop();
+
+ return task;
+}
+
+std::unique_ptr<Task>
+DefaultForegroundTaskRunner::PopTaskFromDelayedQueueLocked(
+ const base::LockGuard<base::Mutex>& guard) {
+ if (delayed_task_queue_.empty()) return {};
+
+ double now = MonotonicallyIncreasingTime();
+ const DelayedEntry& deadline_and_task = delayed_task_queue_.top();
+ if (deadline_and_task.first > now) return {};
+ // The const_cast here is necessary because there does not exist a clean way
+ // to get a unique_ptr out of the priority queue. We provide the priority
+ // queue with a custom comparison operator to make sure that the priority
+ // queue does not access the unique_ptr. Therefore it should be safe to reset
+ // the unique_ptr in the priority queue here. Note that the DelayedEntry is
+ // removed from the priority_queue immediately afterwards.
+ std::unique_ptr<Task> result =
+ std::move(const_cast<DelayedEntry&>(deadline_and_task).second);
+ delayed_task_queue_.pop();
+ return result;
+}
+
+std::unique_ptr<IdleTask> DefaultForegroundTaskRunner::PopTaskFromIdleQueue() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ if (idle_task_queue_.empty()) return {};
+
+ std::unique_ptr<IdleTask> task = std::move(idle_task_queue_.front());
+ idle_task_queue_.pop();
+
+ return task;
+}
+
+void DefaultForegroundTaskRunner::WaitForTask() { event_loop_control_.Wait(); }
+
+} // namespace platform
+} // namespace v8