OLD | NEW |
---|---|
(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 #include <vector> | |
9 | |
10 #include "base/logging.h" | |
11 | |
12 namespace base { | |
13 namespace internal { | |
14 | |
15 struct DelayedTaskManager::DelayedTask { | |
16 DelayedTask() = default; | |
17 DelayedTask(std::unique_ptr<Task> task, | |
18 const PostTaskCallback& post_task_callback, | |
19 size_t index); | |
20 DelayedTask(DelayedTask&& other); | |
21 DelayedTask& operator=(DelayedTask&& other); | |
gab
2016/04/07 21:32:08
Should we explicitly delete the copy constructors?
danakj
2016/04/07 21:39:29
They are not. You can DISALLOW_COPY_AND_ASSIGN and
fdoray
2016/04/08 17:24:51
Done.
| |
22 | |
23 ~DelayedTask() = default; | |
gab
2016/04/07 21:32:08
Can't inline destructor when class has non-POD typ
fdoray
2016/04/08 17:24:51
Done. But does it matter given that we are in the
gab
2016/04/08 18:03:55
Ah true, I guess it matters less, it basically mak
| |
24 | |
25 std::unique_ptr<Task> task; | |
26 PostTaskCallback post_task_callback; | |
27 | |
28 // Ensures that tasks that have the same |delayed_run_time| are sorted | |
29 // according to the order in which they were created. | |
30 size_t index; | |
31 }; | |
gab
2016/04/07 21:32:08
I'd expect the definitions of DelayedTaskManager::
fdoray
2016/04/08 17:24:51
DelayedTaskManager::DelayedTask's definition needs
gab
2016/04/08 18:03:55
Maybe it's fine to just define the entire class in
fdoray
2016/04/11 13:30:54
Done. Defined the entire class inline at the top.
| |
32 | |
33 DelayedTaskManager::DelayedTaskManager(const Closure& delayed_run_time_changed) | |
34 : delayed_run_time_changed_(delayed_run_time_changed) { | |
35 DCHECK(!delayed_run_time_changed_.is_null()); | |
36 } | |
37 | |
38 DelayedTaskManager::~DelayedTaskManager() = default; | |
39 | |
40 void DelayedTaskManager::AddDelayedTask( | |
41 std::unique_ptr<Task> task, | |
42 const PostTaskCallback& post_task_callback) { | |
43 DCHECK(task); | |
44 DCHECK(!post_task_callback.is_null()); | |
45 | |
46 const TimeTicks new_task_delayed_run_time = task->delayed_run_time; | |
47 TimeTicks previous_delayed_run_time; | |
48 | |
49 { | |
50 AutoSchedulerLock auto_lock(lock_); | |
51 | |
52 if (!delayed_tasks_.empty()) | |
53 previous_delayed_run_time = delayed_tasks_.top().task->delayed_run_time; | |
54 | |
55 delayed_tasks_.emplace(std::move(task), post_task_callback, | |
56 next_delayed_task_index_++); | |
57 } | |
58 | |
59 if (previous_delayed_run_time.is_null() || | |
60 new_task_delayed_run_time < previous_delayed_run_time) { | |
61 delayed_run_time_changed_.Run(); | |
62 } | |
63 } | |
64 | |
65 void DelayedTaskManager::PostReadyTasks() { | |
66 const TimeTicks now = Now(); | |
67 | |
68 // Move delayed tasks that are ready for execution into |ready_tasks|. Don't | |
69 // post them right away to avoid imposing an unecessary lock dependency on | |
70 // callbacks. | |
71 std::vector<DelayedTask> ready_tasks; | |
72 | |
73 { | |
74 AutoSchedulerLock auto_lock(lock_); | |
75 while (!delayed_tasks_.empty() && | |
76 delayed_tasks_.top().task->delayed_run_time <= now) { | |
77 // The const_cast for std::move is almost okay since we're immediately | |
78 // moving it to |ready_tasks|. See DelayedTaskComparator::operator() for | |
79 // why it's almost. | |
80 ready_tasks.emplace_back( | |
81 std::move(const_cast<DelayedTask&>(delayed_tasks_.top()))); | |
82 delayed_tasks_.pop(); | |
83 } | |
84 } | |
85 | |
86 // Post delayed tasks that are ready for execution. | |
87 for (auto& delayed_task : ready_tasks) | |
88 delayed_task.post_task_callback.Run(std::move(delayed_task.task)); | |
89 } | |
90 | |
91 TimeTicks DelayedTaskManager::GetNextDelayedRunTime() const { | |
92 AutoSchedulerLock auto_lock(lock_); | |
93 | |
94 if (delayed_tasks_.empty()) | |
95 return TimeTicks(); | |
96 | |
97 return delayed_tasks_.top().task->delayed_run_time; | |
98 } | |
99 | |
100 DelayedTaskManager::DelayedTask::DelayedTask( | |
101 std::unique_ptr<Task> task, | |
102 const PostTaskCallback& post_task_callback, | |
103 size_t index) | |
104 : task(std::move(task)), | |
105 post_task_callback(post_task_callback), | |
106 index(index) {} | |
107 | |
108 DelayedTaskManager::DelayedTask::DelayedTask(DelayedTask&& other) | |
109 : task(std::move(other.task)), | |
110 post_task_callback(other.post_task_callback), | |
111 index(other.index) {} | |
112 | |
113 DelayedTaskManager::DelayedTask& DelayedTaskManager::DelayedTask::operator=( | |
114 DelayedTask&& other) { | |
115 task = std::move(other.task); | |
116 post_task_callback = other.post_task_callback; | |
117 index = other.index; | |
118 return *this; | |
119 } | |
120 | |
121 bool DelayedTaskManager::DelayedTaskComparator::operator()( | |
gab
2016/04/07 21:32:08
Add a comment explaining what this does in the con
fdoray
2016/04/08 17:24:51
Done.
| |
122 const DelayedTask& left, | |
123 const DelayedTask& right) const { | |
124 // Due to STL consistency checks in Windows and const_cast'ing right before | |
125 // popping the DelayedTask, we might actually have null tasks. | |
gab
2016/04/07 21:32:08
s/we might actually have null tasks/null tasks can
| |
126 // To keep the order of the data structure the same, we consider null tasks | |
gab
2016/04/07 21:32:08
s/To keep the order of the data structure the same
fdoray
2016/04/08 17:24:51
Done.
| |
127 // to be the smallest possible |delayed_run_time|. | |
gab
2016/04/07 21:32:08
"smallest possible |delayed_run_time|" is confusin
fdoray
2016/04/08 17:24:51
Done.
| |
128 if (!left.task) | |
gab
2016/04/07 21:32:08
Add:
// Since null tasks is a special case of the
fdoray
2016/04/08 17:24:51
Done.
| |
129 return false; | |
130 if (!right.task) | |
131 return true; | |
gab
2016/04/07 21:32:08
Would it make sense to:
#ifndef NDEBUG
DCHECK(l
fdoray
2016/04/08 17:24:51
Done.
| |
132 if (left.task->delayed_run_time > right.task->delayed_run_time) | |
133 return true; | |
134 if (left.task->delayed_run_time < right.task->delayed_run_time) | |
135 return false; | |
136 return left.index > right.index; | |
137 } | |
138 | |
139 TimeTicks DelayedTaskManager::Now() const { | |
140 return TimeTicks::Now(); | |
141 } | |
142 | |
143 } // namespace internal | |
144 } // namespace base | |
OLD | NEW |