Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: base/task_scheduler/delayed_task_manager.cc

Issue 1806473002: TaskScheduler [9] Delayed Task Manager (Closed) Base URL: https://luckyluke-private.googlesource.com/src@s_5_worker_thread
Patch Set: CR gab #17 Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium 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 "base/task_scheduler/delayed_task_manager.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "base/task_scheduler/utils.h"
11
12 namespace base {
13 namespace internal {
14
15 struct DelayedTaskManager::DelayedTask {
16 DelayedTask(std::unique_ptr<Task> task,
17 scoped_refptr<Sequence> sequence,
18 PriorityQueue* priority_queue,
19 uint64_t index)
20 : task(std::move(task)),
21 sequence(std::move(sequence)),
22 priority_queue(priority_queue),
23 index(index) {}
24
25 DelayedTask(DelayedTask&& other)
26 : task(std::move(other.task)),
27 sequence(std::move(other.sequence)),
28 priority_queue(other.priority_queue),
29 index(other.index) {}
30
31 ~DelayedTask() = default;
32
33 DelayedTask& operator=(DelayedTask&& other) {
34 task = std::move(other.task);
35 sequence = std::move(other.sequence);
36 priority_queue = other.priority_queue;
37 index = other.index;
38 return *this;
39 }
40
41 std::unique_ptr<Task> task;
42
43 // The sequence and priority queue in which |task| is inserted once it
44 // becomes ripe for execution.
45 scoped_refptr<Sequence> sequence;
46 PriorityQueue* priority_queue;
47
48 // Ensures that tasks that have the same |delayed_run_time| are sorted
49 // according to the order in which they were added to the DelayedTaskManager.
50 uint64_t index;
51
52 private:
53 DISALLOW_COPY_AND_ASSIGN(DelayedTask);
54 };
55
56 DelayedTaskManager::DelayedTaskManager(
57 const Closure& on_delayed_run_time_updated)
58 : on_delayed_run_time_updated_(on_delayed_run_time_updated) {
59 DCHECK(!on_delayed_run_time_updated_.is_null());
60 }
61
62 DelayedTaskManager::~DelayedTaskManager() = default;
63
64 void DelayedTaskManager::AddDelayedTask(std::unique_ptr<Task> task,
65 scoped_refptr<Sequence> sequence,
66 PriorityQueue* priority_queue) {
67 DCHECK(task);
68 DCHECK(sequence);
69 DCHECK(priority_queue);
70
71 const TimeTicks new_task_delayed_run_time = task->delayed_run_time;
72 TimeTicks current_delayed_run_time;
73
74 {
75 AutoSchedulerLock auto_lock(lock_);
76
77 if (!delayed_tasks_.empty()) {
78 current_delayed_run_time = delayed_tasks_.top().task->delayed_run_time;
79 }
80
81 delayed_tasks_.emplace(std::move(task), std::move(sequence), priority_queue,
82 delayed_task_index_++);
83 }
84
85 if (current_delayed_run_time.is_null() ||
86 new_task_delayed_run_time < current_delayed_run_time) {
87 on_delayed_run_time_updated_.Run();
88 }
89 }
90
91 void DelayedTaskManager::PostReadyTasks() {
92 const TimeTicks now = Now();
93
94 // Move delayed tasks that are ready for execution into |ready_tasks|. Don't
95 // post them right away to avoid imposing an unecessary lock dependency on
96 // PostTaskNowHelper.
97 std::vector<DelayedTask> ready_tasks;
98
99 {
100 AutoSchedulerLock auto_lock(lock_);
101 while (!delayed_tasks_.empty() &&
102 delayed_tasks_.top().task->delayed_run_time <= now) {
103 // The const_cast for std::move is okay since we're immediately popping
104 // the task from |delayed_tasks_|. See DelayedTaskComparator::operator()
105 // for minor debug-check implications.
106 ready_tasks.emplace_back(
107 std::move(const_cast<DelayedTask&>(delayed_tasks_.top())));
108 delayed_tasks_.pop();
109 }
110 }
111
112 // Post delayed tasks that are ready for execution.
113 for (auto& delayed_task : ready_tasks) {
114 PostTaskNowHelper(std::move(delayed_task.task),
115 std::move(delayed_task.sequence),
116 delayed_task.priority_queue);
117 }
118 }
119
120 TimeTicks DelayedTaskManager::GetDelayedRunTime() const {
121 AutoSchedulerLock auto_lock(lock_);
122
123 if (delayed_tasks_.empty())
124 return TimeTicks();
125
126 return delayed_tasks_.top().task->delayed_run_time;
127 }
128
129 // In std::priority_queue, the largest element is on top. Therefore, this
130 // comparator returns true if the delayed run time of |right| is earlier than
131 // the delayed run time of |left|.
132 bool DelayedTaskManager::DelayedTaskComparator::operator()(
133 const DelayedTask& left,
134 const DelayedTask& right) const {
135 #ifndef NDEBUG
136 // Due to STL consistency checks in Windows and const_cast'ing right before
137 // popping the DelayedTask, a null task can be passed to this comparator in
138 // Debug builds. To satisfy these consistency checks, this comparator
139 // considers null tasks to be the larger than anything.
140 DCHECK(left.task || right.task);
141 if (!left.task)
142 return false;
143 if (!right.task)
144 return true;
145 #else
146 DCHECK(left.task);
147 DCHECK(right.task);
148 #endif // NDEBUG
149 if (left.task->delayed_run_time > right.task->delayed_run_time)
150 return true;
151 if (left.task->delayed_run_time < right.task->delayed_run_time)
152 return false;
153 return left.index > right.index;
154 }
155
156 TimeTicks DelayedTaskManager::Now() const {
157 return TimeTicks::Now();
158 }
159
160 } // namespace internal
161 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698