V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
default-foreground-task-runner.cc
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/libplatform/default-foreground-task-runner.h"
6 
7 #include "src/base/platform/mutex.h"
8 #include "src/libplatform/default-platform.h"
9 
10 namespace v8 {
11 namespace platform {
12 
13 DefaultForegroundTaskRunner::DefaultForegroundTaskRunner(
14  IdleTaskSupport idle_task_support, TimeFunction time_function)
15  : idle_task_support_(idle_task_support), time_function_(time_function) {}
16 
17 void DefaultForegroundTaskRunner::Terminate() {
18  base::MutexGuard guard(&lock_);
19  terminated_ = true;
20 
21  // Drain the task queues.
22  while (!task_queue_.empty()) task_queue_.pop();
23  while (!delayed_task_queue_.empty()) delayed_task_queue_.pop();
24  while (!idle_task_queue_.empty()) idle_task_queue_.pop();
25 }
26 
27 void DefaultForegroundTaskRunner::PostTaskLocked(std::unique_ptr<Task> task,
28  const base::MutexGuard&) {
29  if (terminated_) return;
30  task_queue_.push(std::move(task));
31  event_loop_control_.NotifyOne();
32 }
33 
34 void DefaultForegroundTaskRunner::PostTask(std::unique_ptr<Task> task) {
35  base::MutexGuard guard(&lock_);
36  PostTaskLocked(std::move(task), guard);
37 }
38 
39 double DefaultForegroundTaskRunner::MonotonicallyIncreasingTime() {
40  return time_function_();
41 }
42 
43 void DefaultForegroundTaskRunner::PostDelayedTask(std::unique_ptr<Task> task,
44  double delay_in_seconds) {
45  DCHECK_GE(delay_in_seconds, 0.0);
46  base::MutexGuard guard(&lock_);
47  if (terminated_) return;
48  double deadline = MonotonicallyIncreasingTime() + delay_in_seconds;
49  delayed_task_queue_.push(std::make_pair(deadline, std::move(task)));
50 }
51 
52 void DefaultForegroundTaskRunner::PostIdleTask(std::unique_ptr<IdleTask> task) {
53  CHECK_EQ(IdleTaskSupport::kEnabled, idle_task_support_);
54  base::MutexGuard guard(&lock_);
55  if (terminated_) return;
56  idle_task_queue_.push(std::move(task));
57 }
58 
59 bool DefaultForegroundTaskRunner::IdleTasksEnabled() {
60  return idle_task_support_ == IdleTaskSupport::kEnabled;
61 }
62 
63 std::unique_ptr<Task> DefaultForegroundTaskRunner::PopTaskFromQueue(
64  MessageLoopBehavior wait_for_work) {
65  base::MutexGuard guard(&lock_);
66  // Move delayed tasks that hit their deadline to the main queue.
67  std::unique_ptr<Task> task = PopTaskFromDelayedQueueLocked(guard);
68  while (task) {
69  PostTaskLocked(std::move(task), guard);
70  task = PopTaskFromDelayedQueueLocked(guard);
71  }
72 
73  while (task_queue_.empty()) {
74  if (wait_for_work == MessageLoopBehavior::kDoNotWait) return {};
75  WaitForTaskLocked(guard);
76  }
77 
78  task = std::move(task_queue_.front());
79  task_queue_.pop();
80 
81  return task;
82 }
83 
84 std::unique_ptr<Task>
85 DefaultForegroundTaskRunner::PopTaskFromDelayedQueueLocked(
86  const base::MutexGuard&) {
87  if (delayed_task_queue_.empty()) return {};
88 
89  double now = MonotonicallyIncreasingTime();
90  const DelayedEntry& deadline_and_task = delayed_task_queue_.top();
91  if (deadline_and_task.first > now) return {};
92  // The const_cast here is necessary because there does not exist a clean way
93  // to get a unique_ptr out of the priority queue. We provide the priority
94  // queue with a custom comparison operator to make sure that the priority
95  // queue does not access the unique_ptr. Therefore it should be safe to reset
96  // the unique_ptr in the priority queue here. Note that the DelayedEntry is
97  // removed from the priority_queue immediately afterwards.
98  std::unique_ptr<Task> result =
99  std::move(const_cast<DelayedEntry&>(deadline_and_task).second);
100  delayed_task_queue_.pop();
101  return result;
102 }
103 
104 std::unique_ptr<IdleTask> DefaultForegroundTaskRunner::PopTaskFromIdleQueue() {
105  base::MutexGuard guard(&lock_);
106  if (idle_task_queue_.empty()) return {};
107 
108  std::unique_ptr<IdleTask> task = std::move(idle_task_queue_.front());
109  idle_task_queue_.pop();
110 
111  return task;
112 }
113 
114 void DefaultForegroundTaskRunner::WaitForTaskLocked(const base::MutexGuard&) {
115  event_loop_control_.Wait(&lock_);
116 }
117 
118 } // namespace platform
119 } // namespace v8
Definition: libplatform.h:13