diff options
Diffstat (limited to 'deps/v8/src/libplatform/default-foreground-task-runner.cc')
-rw-r--r-- | deps/v8/src/libplatform/default-foreground-task-runner.cc | 115 |
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 |