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

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

Issue 2698843006: Introduce SchedulerSingleThreadTaskRunnerManager (Closed)
Patch Set: CR Feedback Created 3 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 2017 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/scheduler_single_thread_task_runner_manager.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/synchronization/lock.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/task_scheduler/delayed_task_manager.h"
12 #include "base/task_scheduler/post_task.h"
13 #include "base/task_scheduler/scheduler_worker_pool_params.h"
14 #include "base/task_scheduler/task_tracker.h"
15 #include "base/task_scheduler/task_traits.h"
16 #include "base/test/test_timeouts.h"
17 #include "base/threading/thread.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace base {
21 namespace internal {
22
23 namespace {
24
25 enum WorkerPoolType {
26 BACKGROUND_WORKER_POOL = 0,
27 FOREGROUND_WORKER_POOL,
28 };
29
30 static size_t GetThreadPoolIndexForTraits(const TaskTraits& traits) {
31 return traits.priority() == TaskPriority::BACKGROUND ? BACKGROUND_WORKER_POOL
32 : FOREGROUND_WORKER_POOL;
33 }
34
35 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test {
36 public:
37 TaskSchedulerSingleThreadTaskRunnerManagerTest()
38 : service_thread_("TaskSchedulerServiceThread") {}
39
40 void SetUp() override {
41 service_thread_.Start();
42
43 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy;
44
45 std::vector<SchedulerWorkerPoolParams> params_vector;
46
47 ASSERT_EQ(BACKGROUND_WORKER_POOL, params_vector.size());
48 params_vector.emplace_back("Background", ThreadPriority::BACKGROUND,
49 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max());
50
51 ASSERT_EQ(FOREGROUND_WORKER_POOL, params_vector.size());
52 params_vector.emplace_back("Foreground", ThreadPriority::NORMAL,
53 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max());
54
55 delayed_task_manager_ =
56 MakeUnique<DelayedTaskManager>(service_thread_.task_runner());
57 single_thread_task_runner_manager_ =
58 MakeUnique<SchedulerSingleThreadTaskRunnerManager>(
59 params_vector, Bind(&GetThreadPoolIndexForTraits), &task_tracker_,
60 delayed_task_manager_.get());
61 }
62
63 void TearDown() override {
64 single_thread_task_runner_manager_->JoinForTesting();
65 single_thread_task_runner_manager_.reset();
66 delayed_task_manager_.reset();
67 service_thread_.Stop();
68 }
69
70 protected:
71 std::unique_ptr<SchedulerSingleThreadTaskRunnerManager>
72 single_thread_task_runner_manager_;
73 TaskTracker task_tracker_;
74
75 private:
76 Thread service_thread_;
77 std::unique_ptr<DelayedTaskManager> delayed_task_manager_;
78
79 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTest);
80 };
81
82 void CaptureThreadRef(PlatformThreadRef* thread_ref) {
83 ASSERT_TRUE(thread_ref);
84 *thread_ref = PlatformThread::CurrentRef();
85 }
86
87 void CaptureThreadPriority(ThreadPriority* thread_priority) {
88 ASSERT_TRUE(thread_priority);
89 *thread_priority = PlatformThread::GetCurrentThreadPriority();
90 }
91
92 void ShouldNotRun() {
93 ADD_FAILURE() << "Ran a task that shouldn't run.";
94 }
95
96 } // namespace
97
98 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) {
99 scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
100 single_thread_task_runner_manager_
101 ->CreateSingleThreadTaskRunnerWithTraits(
102 TaskTraits().WithShutdownBehavior(
103 TaskShutdownBehavior::BLOCK_SHUTDOWN));
104 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
105 single_thread_task_runner_manager_
106 ->CreateSingleThreadTaskRunnerWithTraits(
107 TaskTraits().WithShutdownBehavior(
108 TaskShutdownBehavior::BLOCK_SHUTDOWN));
109
110 PlatformThreadRef thread_ref_1;
111 task_runner_1->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_1));
112 PlatformThreadRef thread_ref_2;
113 task_runner_2->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_2));
114
115 task_tracker_.Shutdown();
116
117 ASSERT_FALSE(thread_ref_1.is_null());
118 ASSERT_FALSE(thread_ref_2.is_null());
119 EXPECT_FALSE(thread_ref_1 == thread_ref_2);
gab 2017/02/24 18:44:17 EXPECT_NE?
robliao 2017/02/24 18:45:10 Yeah, that will depend on my PlatformThreadRef cha
120 }
121
122 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) {
123 // Why are events used here instead of the task tracker?
124 // Shutting down can cause priorities to get raised. This means we have to use
125 // events to determine when a task is run.
126 scoped_refptr<SingleThreadTaskRunner> task_runner_background =
127 single_thread_task_runner_manager_
128 ->CreateSingleThreadTaskRunnerWithTraits(
129 TaskTraits().WithPriority(TaskPriority::BACKGROUND));
130 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible =
131 single_thread_task_runner_manager_
132 ->CreateSingleThreadTaskRunnerWithTraits(
133 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE));
134 scoped_refptr<SingleThreadTaskRunner> task_runner_user_blocking =
135 single_thread_task_runner_manager_
136 ->CreateSingleThreadTaskRunnerWithTraits(
137 TaskTraits()
138 .WithPriority(TaskPriority::USER_BLOCKING)
139 .WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN));
140
141 ThreadPriority thread_priority_background;
142 task_runner_background->PostTask(
143 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_background));
144 WaitableEvent waitable_event_background(
145 WaitableEvent::ResetPolicy::MANUAL,
146 WaitableEvent::InitialState::NOT_SIGNALED);
147 task_runner_background->PostTask(
148 FROM_HERE,
149 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_background)));
150
151 ThreadPriority thread_priority_user_visible;
152 task_runner_user_visible->PostTask(
153 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_user_visible));
154 WaitableEvent waitable_event_user_visible(
155 WaitableEvent::ResetPolicy::MANUAL,
156 WaitableEvent::InitialState::NOT_SIGNALED);
157 task_runner_user_visible->PostTask(
158 FROM_HERE,
159 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_user_visible)));
160
161 ThreadPriority thread_priority_user_blocking;
162 task_runner_user_blocking->PostTask(
163 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_user_blocking));
164 WaitableEvent waitable_event_user_blocking(
165 WaitableEvent::ResetPolicy::MANUAL,
166 WaitableEvent::InitialState::NOT_SIGNALED);
167 task_runner_user_blocking->PostTask(
168 FROM_HERE,
169 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_user_blocking)));
170
171 waitable_event_background.Wait();
172 waitable_event_user_visible.Wait();
173 waitable_event_user_blocking.Wait();
174
175 if (Lock::HandlesMultipleThreadPriorities())
176 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background);
177 else
178 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background);
179 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible);
180 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking);
181 }
182
183 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) {
184 auto task_runner = single_thread_task_runner_manager_
185 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits());
186 task_tracker_.Shutdown();
187 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRun)));
188 }
189
190 // Verify that a Task runs shortly after its delay expires.
191 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) {
192 TimeTicks start_time = TimeTicks::Now();
193
194 // Post a task with a short delay.
195 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
196 WaitableEvent::InitialState::NOT_SIGNALED);
197 auto task_runner = single_thread_task_runner_manager_
198 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits());
199 EXPECT_TRUE(task_runner->PostDelayedTask(
200 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_ran)),
201 TestTimeouts::tiny_timeout()));
202
203 // Wait until the task runs.
204 task_ran.Wait();
205
206 // Expect the task to run after its delay expires, but not more than 250 ms
207 // after that.
208 const TimeDelta actual_delay = TimeTicks::Now() - start_time;
209 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout());
210 EXPECT_LT(actual_delay,
211 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout());
212 }
213
214 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest,
215 RunsTasksOnCurrentThread) {
216 scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
217 single_thread_task_runner_manager_
218 ->CreateSingleThreadTaskRunnerWithTraits(
219 TaskTraits().WithShutdownBehavior(
220 TaskShutdownBehavior::BLOCK_SHUTDOWN));
221 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
222 single_thread_task_runner_manager_
223 ->CreateSingleThreadTaskRunnerWithTraits(
224 TaskTraits().WithShutdownBehavior(
225 TaskShutdownBehavior::BLOCK_SHUTDOWN));
226
227 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread());
228 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread());
229
230 task_runner_1->PostTask(
231 FROM_HERE, Bind(
232 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1,
233 scoped_refptr<SingleThreadTaskRunner> task_runner_2) {
234 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread());
235 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread());
236 },
237 task_runner_1, task_runner_2));
238
239 task_runner_2->PostTask(
240 FROM_HERE, Bind(
241 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1,
242 scoped_refptr<SingleThreadTaskRunner> task_runner_2) {
243 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread());
244 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread());
245 },
246 task_runner_1, task_runner_2));
247
248 task_tracker_.Shutdown();
249 }
250
251 } // namespace internal
252 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/scheduler_single_thread_task_runner_manager.cc ('k') | base/task_scheduler/scheduler_worker_pool_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698