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

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 danakj #29 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/scheduler_task_executor.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 SchedulerTaskExecutor* executor,
19 uint64_t index)
20 : task(std::move(task)),
21 sequence(std::move(sequence)),
22 executor(executor),
23 index(index) {}
24
25 DelayedTask(DelayedTask&& other) = default;
26
27 ~DelayedTask() = default;
28
29 DelayedTask& operator=(DelayedTask&& other) = default;
30
31 // |task| will be posted to |executor| as part of |sequence| when it becomes
32 // ripe for execution.
33 std::unique_ptr<Task> task;
34 scoped_refptr<Sequence> sequence;
35 SchedulerTaskExecutor* executor;
36
37 // Ensures that tasks that have the same |delayed_run_time| are sorted
38 // according to the order in which they were added to the DelayedTaskManager.
39 uint64_t index;
40
41 private:
42 DISALLOW_COPY_AND_ASSIGN(DelayedTask);
43 };
44
45 DelayedTaskManager::DelayedTaskManager(
46 const Closure& on_delayed_run_time_updated)
47 : on_delayed_run_time_updated_(on_delayed_run_time_updated) {
48 DCHECK(!on_delayed_run_time_updated_.is_null());
49 }
50
51 DelayedTaskManager::~DelayedTaskManager() = default;
52
53 void DelayedTaskManager::AddDelayedTask(std::unique_ptr<Task> task,
54 scoped_refptr<Sequence> sequence,
55 SchedulerTaskExecutor* executor) {
56 DCHECK(task);
57 DCHECK(sequence);
58 DCHECK(executor);
59
60 const TimeTicks new_task_delayed_run_time = task->delayed_run_time;
61 TimeTicks current_delayed_run_time;
62
63 {
64 AutoSchedulerLock auto_lock(lock_);
65
66 if (!delayed_tasks_.empty())
67 current_delayed_run_time = delayed_tasks_.top().task->delayed_run_time;
68
69 delayed_tasks_.emplace(std::move(task), std::move(sequence), executor,
70 ++delayed_task_index_);
71 }
72
73 if (current_delayed_run_time.is_null() ||
74 new_task_delayed_run_time < current_delayed_run_time) {
75 on_delayed_run_time_updated_.Run();
76 }
77 }
78
79 void DelayedTaskManager::PostReadyTasks() {
80 const TimeTicks now = Now();
81
82 // Move delayed tasks that are ready for execution into |ready_tasks|. Don't
83 // post them right away to avoid imposing an unecessary lock dependency on
84 // PostTaskNowHelper.
85 std::vector<DelayedTask> ready_tasks;
86
87 {
88 AutoSchedulerLock auto_lock(lock_);
89 while (!delayed_tasks_.empty() &&
90 delayed_tasks_.top().task->delayed_run_time <= now) {
91 // The const_cast for std::move is okay since we're immediately popping
92 // the task from |delayed_tasks_|. See DelayedTaskComparator::operator()
93 // for minor debug-check implications.
94 ready_tasks.push_back(
95 std::move(const_cast<DelayedTask&>(delayed_tasks_.top())));
96 delayed_tasks_.pop();
97 }
98 }
99
100 // Post delayed tasks that are ready for execution.
101 for (auto& delayed_task : ready_tasks) {
102 delayed_task.executor->PostTaskWithSequence(
103 std::move(delayed_task.task), std::move(delayed_task.sequence));
104 }
105 }
106
107 TimeTicks DelayedTaskManager::GetDelayedRunTime() const {
108 AutoSchedulerLock auto_lock(lock_);
109
110 if (delayed_tasks_.empty())
111 return TimeTicks();
112
113 return delayed_tasks_.top().task->delayed_run_time;
114 }
115
116 // In std::priority_queue, the largest element is on top. Therefore, this
117 // comparator returns true if the delayed run time of |right| is earlier than
118 // the delayed run time of |left|.
119 bool DelayedTaskManager::DelayedTaskComparator::operator()(
120 const DelayedTask& left,
121 const DelayedTask& right) const {
122 #ifndef NDEBUG
123 // Due to STL consistency checks in Windows and const_cast'ing right before
124 // popping the DelayedTask, a null task can be passed to this comparator in
125 // Debug builds. To satisfy these consistency checks, this comparator
126 // considers null tasks to be the larger than anything.
127 DCHECK(left.task || right.task);
128 if (!left.task)
129 return false;
130 if (!right.task)
131 return true;
132 #else
133 DCHECK(left.task);
134 DCHECK(right.task);
135 #endif // NDEBUG
136 if (left.task->delayed_run_time > right.task->delayed_run_time)
137 return true;
138 if (left.task->delayed_run_time < right.task->delayed_run_time)
139 return false;
140 return left.index > right.index;
141 }
142
143 TimeTicks DelayedTaskManager::Now() const {
144 return TimeTicks::Now();
145 }
146
147 } // namespace internal
148 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/delayed_task_manager.h ('k') | base/task_scheduler/delayed_task_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698