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

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

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