1 // Copyright 2018 The Chromium Authors
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 "base/task/sequence_manager/tasks.h"
6
7 #include "base/task/sequence_manager/task_order.h"
8
9 namespace base {
10 namespace sequence_manager {
11
Task(internal::PostedTask posted_task,EnqueueOrder sequence_order,EnqueueOrder enqueue_order,TimeTicks queue_time,WakeUpResolution resolution,TimeDelta leeway)12 Task::Task(internal::PostedTask posted_task,
13 EnqueueOrder sequence_order,
14 EnqueueOrder enqueue_order,
15 TimeTicks queue_time,
16 WakeUpResolution resolution,
17 TimeDelta leeway)
18 : PendingTask(posted_task.location,
19 std::move(posted_task.callback),
20 queue_time,
21 absl::holds_alternative<base::TimeTicks>(
22 posted_task.delay_or_delayed_run_time)
23 ? absl::get<base::TimeTicks>(
24 posted_task.delay_or_delayed_run_time)
25 : base::TimeTicks(),
26 leeway,
27 posted_task.delay_policy),
28 nestable(posted_task.nestable),
29 task_type(posted_task.task_type),
30 task_runner(std::move(posted_task.task_runner)),
31 enqueue_order_(enqueue_order),
32 delayed_task_handle_delegate_(
33 std::move(posted_task.delayed_task_handle_delegate)) {
34 DCHECK(!absl::holds_alternative<base::TimeDelta>(
35 posted_task.delay_or_delayed_run_time) ||
36 absl::get<base::TimeDelta>(posted_task.delay_or_delayed_run_time)
37 .is_zero());
38 // We use |sequence_num| when comparing PendingTask for ordering purposes
39 // and it may wrap around to a negative number during the static cast, hence,
40 // TaskQueueImpl::DelayedIncomingQueue is especially sensitive to a potential
41 // change of |PendingTask::sequence_num|'s type.
42 static_assert(std::is_same_v<decltype(sequence_num), int>, "");
43 sequence_num = static_cast<int>(sequence_order);
44 this->is_high_res = resolution == WakeUpResolution::kHigh;
45 }
46
47 Task::Task(Task&& move_from) = default;
48
49 Task::~Task() = default;
50
51 Task& Task::operator=(Task&& other) = default;
52
task_order() const53 TaskOrder Task::task_order() const {
54 return TaskOrder(
55 enqueue_order(),
56 delayed_run_time.is_null() ? TimeTicks() : latest_delayed_run_time(),
57 sequence_num);
58 }
59
SetHeapHandle(HeapHandle heap_handle)60 void Task::SetHeapHandle(HeapHandle heap_handle) {
61 if (!delayed_task_handle_delegate_)
62 return;
63
64 delayed_task_handle_delegate_->SetHeapHandle(heap_handle);
65 }
66
ClearHeapHandle()67 void Task::ClearHeapHandle() {
68 if (!delayed_task_handle_delegate_)
69 return;
70 delayed_task_handle_delegate_->ClearHeapHandle();
71 }
72
GetHeapHandle() const73 HeapHandle Task::GetHeapHandle() const {
74 if (!delayed_task_handle_delegate_)
75 return HeapHandle::Invalid();
76 return delayed_task_handle_delegate_->GetHeapHandle();
77 }
78
IsCanceled() const79 bool Task::IsCanceled() const {
80 CHECK(task);
81 if (task.IsCancelled()) {
82 return true;
83 }
84
85 return delayed_task_handle_delegate_.WasInvalidated();
86 }
87
WillRunTask()88 bool Task::WillRunTask() {
89 if (delayed_task_handle_delegate_.WasInvalidated()) {
90 return false;
91 }
92 if (delayed_task_handle_delegate_) {
93 delayed_task_handle_delegate_->WillRunTask();
94 }
95 return true;
96 }
97
earliest_time() const98 TimeTicks WakeUp::earliest_time() const {
99 if (delay_policy == subtle::DelayPolicy::kFlexiblePreferEarly)
100 return time - leeway;
101 return time;
102 }
103
latest_time() const104 TimeTicks WakeUp::latest_time() const {
105 if (delay_policy == subtle::DelayPolicy::kFlexibleNoSooner)
106 return time + leeway;
107 return time;
108 }
109
110 namespace internal {
PostedTask(scoped_refptr<SequencedTaskRunner> task_runner,OnceClosure callback,Location location,TimeDelta delay,Nestable nestable,TaskType task_type,WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate)111 PostedTask::PostedTask(
112 scoped_refptr<SequencedTaskRunner> task_runner,
113 OnceClosure callback,
114 Location location,
115 TimeDelta delay,
116 Nestable nestable,
117 TaskType task_type,
118 WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate)
119 : callback(std::move(callback)),
120 location(location),
121 nestable(nestable),
122 task_type(task_type),
123 delay_or_delayed_run_time(delay),
124 task_runner(std::move(task_runner)),
125 delayed_task_handle_delegate(std::move(delayed_task_handle_delegate)) {}
126
PostedTask(scoped_refptr<SequencedTaskRunner> task_runner,OnceClosure callback,Location location,TimeTicks delayed_run_time,subtle::DelayPolicy delay_policy,Nestable nestable,TaskType task_type,WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate)127 PostedTask::PostedTask(
128 scoped_refptr<SequencedTaskRunner> task_runner,
129 OnceClosure callback,
130 Location location,
131 TimeTicks delayed_run_time,
132 subtle::DelayPolicy delay_policy,
133 Nestable nestable,
134 TaskType task_type,
135 WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate)
136 : callback(std::move(callback)),
137 location(location),
138 nestable(nestable),
139 task_type(task_type),
140 delay_or_delayed_run_time(delayed_run_time),
141 delay_policy(delay_policy),
142 task_runner(std::move(task_runner)),
143 delayed_task_handle_delegate(std::move(delayed_task_handle_delegate)) {}
144
145 PostedTask::PostedTask(PostedTask&& move_from) noexcept = default;
146 PostedTask::~PostedTask() = default;
147
148 } // namespace internal
149 } // namespace sequence_manager
150 } // namespace base
151