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

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

Issue 1685423002: Task Scheduler. (Closed) Base URL: https://luckyluke-private.googlesource.com/src@a_master
Patch Set: Created 4 years, 10 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/worker_thread.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback_forward.h"
10 #include "base/logging.h"
11 #include "base/synchronization/condition_variable.h"
12 #include "base/task_scheduler/delayed_task_manager.h"
13 #include "base/task_scheduler/priority_queue.h"
14 #include "base/task_scheduler/scheduler_lock.h"
15 #include "base/task_scheduler/shutdown_manager.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19 namespace task_scheduler {
20
21 class TaskSchedulerWorkerThreadTest : public testing::Test {
22 protected:
23 TaskSchedulerWorkerThreadTest()
24 : worker_thread_(WorkerThread::CreateWorkerThread(
25 ThreadPriority::NORMAL,
26 &shared_priority_queue_,
27 Bind(&TaskSchedulerWorkerThreadTest::ReinsertSequenceCallback,
28 Unretained(this)),
29 Bind(&TaskSchedulerWorkerThreadTest::BecomesIdleCallback,
30 Unretained(this)),
31 &delayed_task_manager_,
32 &shutdown_manager_)),
33 cv_(lock_.RawLockForConditionVariable()),
34 last_posted_task_index_(0),
35 last_run_task_index_(0),
36 ran_task_that_should_not_run_(false),
37 ran_tasks_in_wrong_order_(true),
38 shared_priority_queue_(Bind(&DoNothing)),
39 delayed_task_manager_(
40 Bind(&WorkerThread::WakeUp, Unretained(worker_thread_.get())),
41 &shutdown_manager_) {}
42
43 WorkerThread::ReinsertSequenceCallback GetReinsertSequenceCallback() {
44 return Bind(&TaskSchedulerWorkerThreadTest::ReinsertSequenceCallback,
45 Unretained(this));
46 }
47
48 Closure GetTaskThatShouldRunClosure() {
49 ++last_posted_task_index_;
50 return Bind(&TaskSchedulerWorkerThreadTest::RunTaskThatShouldRun,
51 Unretained(this), last_posted_task_index_);
52 }
53
54 Closure GetTaskThatShouldNotRunClosure() {
55 return Bind(&TaskSchedulerWorkerThreadTest::RunTaskThatShouldNotRun,
56 Unretained(this));
57 }
58
59 void WaitUntilLastPostedTaskHasRun() {
60 AutoSchedulerLock auto_lock(lock_);
61 while (last_posted_task_index_ != last_run_task_index_)
62 cv_.Wait();
63 }
64
65 void Shutdown() {
66 shutdown_manager_.Shutdown();
67 worker_thread_->JoinForTesting();
68 }
69
70 bool ran_task_that_should_not_run() const {
71 return ran_task_that_should_not_run_;
72 }
73
74 scoped_ptr<WorkerThread> worker_thread_;
75 ShutdownManager shutdown_manager_;
76
77 private:
78 void ReinsertSequenceCallback(scoped_refptr<Sequence> sequence,
79 const WorkerThread* worker_thread) {
80 NOTREACHED();
81 }
82
83 void BecomesIdleCallback(WorkerThread* worker_thread) {
84 // TODO(fdoray).
85 }
86
87 void RunTaskThatShouldRun(size_t index) {
88 AutoSchedulerLock auto_lock(lock_);
89
90 if (index != last_run_task_index_ + 1)
91 ran_tasks_in_wrong_order_ = true;
92
93 last_run_task_index_ = index;
94 cv_.Signal();
95 }
96
97 void RunTaskThatShouldNotRun() { ran_task_that_should_not_run_ = true; }
98
99 // Lock protecting |cv_|.
100 SchedulerLock lock_;
101
102 // Condition variable signaled each time a task completes its execution.
103 ConditionVariable cv_;
104
105 // Index of the last posted task.
106 size_t last_posted_task_index_;
107
108 // Index of the last run task.
109 size_t last_run_task_index_;
110
111 // True if a task that shouldn't run has run.
112 bool ran_task_that_should_not_run_;
113
114 // True if tasks were run in the wrong order.
115 bool ran_tasks_in_wrong_order_;
116
117 PriorityQueue shared_priority_queue_;
118
119 DelayedTaskManager delayed_task_manager_;
120 };
121
122 TEST_F(TaskSchedulerWorkerThreadTest, PostSingleTask) {
123 ASSERT_NE(nullptr, worker_thread_.get());
124
125 worker_thread_->CreateTaskRunnerWithTraits(TaskTraits(),
126 ExecutionMode::SINGLE_THREADED)
127 ->PostTask(FROM_HERE, GetTaskThatShouldRunClosure());
128
129 WaitUntilLastPostedTaskHasRun();
130 Shutdown();
131 }
132
133 TEST_F(TaskSchedulerWorkerThreadTest, PostMultipleTasksNoWaitBetweenPosts) {
134 ASSERT_NE(nullptr, worker_thread_.get());
135
136 auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(
137 TaskTraits(), ExecutionMode::SINGLE_THREADED);
138
139 for (size_t i = 0; i < 100; ++i)
140 task_runner->PostTask(FROM_HERE, GetTaskThatShouldRunClosure());
141
142 WaitUntilLastPostedTaskHasRun();
143 Shutdown();
144 }
145
146 TEST_F(TaskSchedulerWorkerThreadTest, PostMultipleTasksWaitBetweenPosts) {
147 ASSERT_NE(nullptr, worker_thread_.get());
148
149 auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(
150 TaskTraits(), ExecutionMode::SINGLE_THREADED);
151
152 for (size_t i = 0; i < 100; ++i) {
153 task_runner->PostTask(FROM_HERE, GetTaskThatShouldRunClosure());
154 WaitUntilLastPostedTaskHasRun();
155 }
156
157 Shutdown();
158 }
159
160 TEST_F(TaskSchedulerWorkerThreadTest, PostMultipleTasksTwoTaskRunners) {
161 ASSERT_NE(nullptr, worker_thread_.get());
162
163 auto task_runner_a = worker_thread_->CreateTaskRunnerWithTraits(
164 TaskTraits(), ExecutionMode::SINGLE_THREADED);
165 auto task_runner_b = worker_thread_->CreateTaskRunnerWithTraits(
166 TaskTraits(), ExecutionMode::SINGLE_THREADED);
167
168 for (size_t i = 0; i < 100; ++i) {
169 task_runner_a->PostTask(FROM_HERE, GetTaskThatShouldRunClosure());
170 task_runner_b->PostTask(FROM_HERE, GetTaskThatShouldRunClosure());
171 }
172
173 WaitUntilLastPostedTaskHasRun();
174
175 Shutdown();
176 }
177
178 TEST_F(TaskSchedulerWorkerThreadTest, PostDelayedTasks) {
179 ASSERT_NE(nullptr, worker_thread_.get());
180
181 auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(
182 TaskTraits(), ExecutionMode::SINGLE_THREADED);
183
184 for (size_t i = 0; i < 10; ++i) {
185 task_runner->PostDelayedTask(FROM_HERE, GetTaskThatShouldRunClosure(),
186 TimeDelta::FromMilliseconds(i * 50));
187 }
188
189 WaitUntilLastPostedTaskHasRun();
190
191 Shutdown();
192 }
193
194 TEST_F(TaskSchedulerWorkerThreadTest, ShutdownBehavior) {
195 ASSERT_NE(nullptr, worker_thread_.get());
196
197 shutdown_manager_.SetIsShuttingDownForTesting();
198
199 // Post tasks with different shutdown behaviors.
200 worker_thread_->CreateTaskRunnerWithTraits(
201 TaskTraits().WithShutdownBehavior(
202 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN),
203 ExecutionMode::SINGLE_THREADED)
204 ->PostTask(FROM_HERE, GetTaskThatShouldNotRunClosure());
205 worker_thread_->CreateTaskRunnerWithTraits(
206 TaskTraits().WithShutdownBehavior(
207 TaskShutdownBehavior::SKIP_ON_SHUTDOWN),
208 ExecutionMode::SINGLE_THREADED)
209 ->PostTask(FROM_HERE, GetTaskThatShouldNotRunClosure());
210 worker_thread_->CreateTaskRunnerWithTraits(
211 TaskTraits().WithShutdownBehavior(
212 TaskShutdownBehavior::BLOCK_SHUTDOWN),
213 ExecutionMode::SINGLE_THREADED)
214 ->PostTask(FROM_HERE, GetTaskThatShouldRunClosure());
215
216 WaitUntilLastPostedTaskHasRun();
217 Shutdown();
218 EXPECT_FALSE(ran_task_that_should_not_run());
219 }
220
221 } // namespace task_scheduler
222 } // namespace base
OLDNEW
« base/task_scheduler/worker_thread.cc ('K') | « base/task_scheduler/worker_thread.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698