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

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: Initial implementation for review. 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 #include <vector>
9
10 #include "base/logging.h"
11
12 namespace base {
13 namespace internal {
14
15 DelayedTaskManager::DelayedTaskManager(const Closure& delayed_run_time_changed)
16 : delayed_run_time_changed_(delayed_run_time_changed) {
17 DCHECK(!delayed_run_time_changed_.is_null());
18 }
19
20 DelayedTaskManager::~DelayedTaskManager() = default;
21
22 void DelayedTaskManager::AddDelayedTask(
23 std::unique_ptr<Task> task,
24 const PostTaskCallback& post_task_callback) {
25 DCHECK(task);
26 DCHECK(!post_task_callback.is_null());
27
28 const TimeTicks new_task_delayed_run_time = task->delayed_run_time;
29 TimeTicks previous_delayed_run_time;
30
31 {
32 AutoSchedulerLock auto_lock(lock_);
33
34 DelayedTask delayed_task;
35 delayed_task.task = std::move(task);
36 delayed_task.post_task_callback = post_task_callback;
37 delayed_task.index = next_delayed_task_index_++;
38
39 if (!delayed_tasks_.empty())
robliao 2016/04/01 20:48:25 Let's move this before the DelayedTask block above
fdoray 2016/04/01 21:21:57 Done.
40 previous_delayed_run_time = delayed_tasks_.top().task->delayed_run_time;
41
42 delayed_tasks_.emplace(std::move(delayed_task));
43 }
44
45 if (previous_delayed_run_time.is_null() ||
46 new_task_delayed_run_time < previous_delayed_run_time) {
47 delayed_run_time_changed_.Run();
48 }
49 }
50
51 void DelayedTaskManager::PostReadyTasks() {
52 const TimeTicks now = Now();
53
54 // Move delayed tasks that are ready for execution into |ready_tasks|. Don't
55 // post them right away to avoid imposing an unecessary lock dependency on
56 // callbacks.
57 std::vector<DelayedTask> ready_tasks;
58
59 {
60 AutoSchedulerLock auto_lock(lock_);
61 while (!delayed_tasks_.empty() &&
62 delayed_tasks_.top().task->delayed_run_time <= now) {
63 // The const_cast for std::move is almost okay since we're immediately
64 // moving it to |ready_tasks|. See DelayedTask::operator< for why it's
65 // almost.
66 ready_tasks.push_back(
robliao 2016/04/01 20:48:25 This can be an emplace_back.
fdoray 2016/04/01 21:21:57 Done.
67 std::move(const_cast<DelayedTask&>(delayed_tasks_.top())));
68 delayed_tasks_.pop();
69 }
70 }
71
72 // Post delayed tasks that are ready for execution.
73 for (auto& delayed_task : ready_tasks)
74 delayed_task.post_task_callback.Run(std::move(delayed_task.task));
75 }
76
77 TimeTicks DelayedTaskManager::GetNextDelayedRunTime() const {
78 AutoSchedulerLock auto_lock(lock_);
79
80 if (delayed_tasks_.empty())
81 return TimeTicks();
82
83 return delayed_tasks_.top().task->delayed_run_time;
84 }
85
86 TimeTicks DelayedTaskManager::Now() {
87 return TimeTicks::Now();
88 }
89
90 DelayedTaskManager::DelayedTask::DelayedTask() = default;
91
92 DelayedTaskManager::DelayedTask::~DelayedTask() = default;
93
94 DelayedTaskManager::DelayedTask::DelayedTask(DelayedTask&& other)
95 : task(std::move(other.task)),
96 post_task_callback(other.post_task_callback),
97 index(other.index) {}
98
99 DelayedTaskManager::DelayedTask& DelayedTaskManager::DelayedTask::operator=(
100 DelayedTask&& other) {
101 task = std::move(other.task);
102 post_task_callback = other.post_task_callback;
103 index = other.index;
104 return *this;
105 }
106
107 bool DelayedTaskManager::DelayedTask::operator<(
108 const DelayedTask& other) const {
109 // Due to STL consistency checks in Windows and const_cast'ing right before
110 // popping the DelayedTask, we might actually have null tasks.
111 // To keep the order of the data structure the same, we consider null tasks
112 // to be the smallest possible |delayed_run_time|.
113 if (!task)
114 return false;
115 if (!other.task)
116 return true;
117 if (task->delayed_run_time > other.task->delayed_run_time)
118 return true;
119 if (task->delayed_run_time < other.task->delayed_run_time)
120 return false;
121 return index > other.index;
122 }
123
124 } // namespace internal
125 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698