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 DCHECK(!delayed_task_handle_delegate_);
83 return true;
84 }
85
86 return delayed_task_handle_delegate_.WasInvalidated();
87 }
88
WillRunTask()89 bool Task::WillRunTask() {
90 if (delayed_task_handle_delegate_.WasInvalidated()) {
91 return false;
92 }
93 if (delayed_task_handle_delegate_) {
94 delayed_task_handle_delegate_->WillRunTask();
95 }
96 return true;
97 }
98
earliest_time() const99 TimeTicks WakeUp::earliest_time() const {
100 if (delay_policy == subtle::DelayPolicy::kFlexiblePreferEarly)
101 return time - leeway;
102 return time;
103 }
104
latest_time() const105 TimeTicks WakeUp::latest_time() const {
106 if (delay_policy == subtle::DelayPolicy::kFlexibleNoSooner)
107 return time + leeway;
108 return time;
109 }
110
111 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)112 PostedTask::PostedTask(
113 scoped_refptr<SequencedTaskRunner> task_runner,
114 OnceClosure callback,
115 Location location,
116 TimeDelta delay,
117 Nestable nestable,
118 TaskType task_type,
119 WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate)
120 : callback(std::move(callback)),
121 location(location),
122 nestable(nestable),
123 task_type(task_type),
124 delay_or_delayed_run_time(delay),
125 task_runner(std::move(task_runner)),
126 delayed_task_handle_delegate(std::move(delayed_task_handle_delegate)) {}
127
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)128 PostedTask::PostedTask(
129 scoped_refptr<SequencedTaskRunner> task_runner,
130 OnceClosure callback,
131 Location location,
132 TimeTicks delayed_run_time,
133 subtle::DelayPolicy delay_policy,
134 Nestable nestable,
135 TaskType task_type,
136 WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate)
137 : callback(std::move(callback)),
138 location(location),
139 nestable(nestable),
140 task_type(task_type),
141 delay_or_delayed_run_time(delayed_run_time),
142 delay_policy(delay_policy),
143 task_runner(std::move(task_runner)),
144 delayed_task_handle_delegate(std::move(delayed_task_handle_delegate)) {}
145
146 PostedTask::PostedTask(PostedTask&& move_from) noexcept = default;
147 PostedTask::~PostedTask() = default;
148
149 } // namespace internal
150 } // namespace sequence_manager
151 } // namespace base
152