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

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

Issue 2902753003: Implement Shared SingleThreadTaskRunners in the Task Scheduler (Closed)
Patch Set: Change Dependent Change Created 3 years, 7 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
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" 5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/synchronization/atomic_flag.h" 9 #include "base/synchronization/atomic_flag.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
12 #include "base/task_scheduler/delayed_task_manager.h" 12 #include "base/task_scheduler/delayed_task_manager.h"
13 #include "base/task_scheduler/post_task.h" 13 #include "base/task_scheduler/post_task.h"
14 #include "base/task_scheduler/scheduler_worker_pool_params.h" 14 #include "base/task_scheduler/scheduler_worker_pool_params.h"
15 #include "base/task_scheduler/task_tracker.h" 15 #include "base/task_scheduler/task_tracker.h"
16 #include "base/task_scheduler/task_traits.h" 16 #include "base/task_scheduler/task_traits.h"
17 #include "base/test/gtest_util.h"
17 #include "base/test/test_timeouts.h" 18 #include "base/test/test_timeouts.h"
18 #include "base/threading/platform_thread.h" 19 #include "base/threading/platform_thread.h"
19 #include "base/threading/simple_thread.h" 20 #include "base/threading/simple_thread.h"
20 #include "base/threading/thread.h" 21 #include "base/threading/thread.h"
21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
22 23
23 #if defined(OS_WIN) 24 #if defined(OS_WIN)
24 #include <windows.h> 25 #include <windows.h>
25 #include <objbase.h> 26 #include <objbase.h>
26 27
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 void CaptureThreadRef(PlatformThreadRef* thread_ref) { 76 void CaptureThreadRef(PlatformThreadRef* thread_ref) {
76 ASSERT_TRUE(thread_ref); 77 ASSERT_TRUE(thread_ref);
77 *thread_ref = PlatformThread::CurrentRef(); 78 *thread_ref = PlatformThread::CurrentRef();
78 } 79 }
79 80
80 void CaptureThreadPriority(ThreadPriority* thread_priority) { 81 void CaptureThreadPriority(ThreadPriority* thread_priority) {
81 ASSERT_TRUE(thread_priority); 82 ASSERT_TRUE(thread_priority);
82 *thread_priority = PlatformThread::GetCurrentThreadPriority(); 83 *thread_priority = PlatformThread::GetCurrentThreadPriority();
83 } 84 }
84 85
86 void CaptureThreadName(std::string* thread_name) {
87 *thread_name = PlatformThread::GetName();
88 }
89
85 void ShouldNotRun() { 90 void ShouldNotRun() {
86 ADD_FAILURE() << "Ran a task that shouldn't run."; 91 ADD_FAILURE() << "Ran a task that shouldn't run.";
87 } 92 }
88 93
89 } // namespace 94 } // namespace
90 95
91 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { 96 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) {
92 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = 97 scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
93 single_thread_task_runner_manager_ 98 single_thread_task_runner_manager_
94 ->CreateSingleThreadTaskRunnerWithTraits( 99 ->CreateSingleThreadTaskRunnerWithTraits(
95 "A", ThreadPriority::NORMAL, 100 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
96 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); 101 SingleThreadTaskRunnerThreadMode::DEDICATED);
97 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = 102 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
98 single_thread_task_runner_manager_ 103 single_thread_task_runner_manager_
99 ->CreateSingleThreadTaskRunnerWithTraits( 104 ->CreateSingleThreadTaskRunnerWithTraits(
100 "B", ThreadPriority::NORMAL, 105 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
101 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); 106 SingleThreadTaskRunnerThreadMode::DEDICATED);
102 107
103 PlatformThreadRef thread_ref_1; 108 PlatformThreadRef thread_ref_1;
104 task_runner_1->PostTask(FROM_HERE, 109 task_runner_1->PostTask(FROM_HERE,
105 BindOnce(&CaptureThreadRef, &thread_ref_1)); 110 BindOnce(&CaptureThreadRef, &thread_ref_1));
106 PlatformThreadRef thread_ref_2; 111 PlatformThreadRef thread_ref_2;
107 task_runner_2->PostTask(FROM_HERE, 112 task_runner_2->PostTask(FROM_HERE,
108 BindOnce(&CaptureThreadRef, &thread_ref_2)); 113 BindOnce(&CaptureThreadRef, &thread_ref_2));
109 114
110 task_tracker_.Shutdown(); 115 task_tracker_.Shutdown();
111 116
112 ASSERT_FALSE(thread_ref_1.is_null()); 117 ASSERT_FALSE(thread_ref_1.is_null());
113 ASSERT_FALSE(thread_ref_2.is_null()); 118 ASSERT_FALSE(thread_ref_2.is_null());
114 EXPECT_NE(thread_ref_1, thread_ref_2); 119 EXPECT_NE(thread_ref_1, thread_ref_2);
115 } 120 }
116 121
117 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { 122 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, SameThreadUsed) {
123 scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
124 single_thread_task_runner_manager_
125 ->CreateSingleThreadTaskRunnerWithTraits(
126 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
127 SingleThreadTaskRunnerThreadMode::SHARED);
128 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
129 single_thread_task_runner_manager_
130 ->CreateSingleThreadTaskRunnerWithTraits(
131 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
132 SingleThreadTaskRunnerThreadMode::SHARED);
133
134 PlatformThreadRef thread_ref_1;
135 task_runner_1->PostTask(FROM_HERE,
136 BindOnce(&CaptureThreadRef, &thread_ref_1));
137 PlatformThreadRef thread_ref_2;
138 task_runner_2->PostTask(FROM_HERE,
139 BindOnce(&CaptureThreadRef, &thread_ref_2));
140
141 task_tracker_.Shutdown();
142
143 ASSERT_FALSE(thread_ref_1.is_null());
144 ASSERT_FALSE(thread_ref_2.is_null());
145 EXPECT_EQ(thread_ref_1, thread_ref_2);
146 }
147
148 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest,
149 RunsTasksOnCurrentThread) {
gab 2017/05/25 18:47:00 This test should work in both modes, parametrize a
robliao 2017/05/30 20:01:07 Since we do check the thread handle for the COM ca
150 scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
151 single_thread_task_runner_manager_
152 ->CreateSingleThreadTaskRunnerWithTraits(
153 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
154 SingleThreadTaskRunnerThreadMode::DEDICATED);
155 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
156 single_thread_task_runner_manager_
157 ->CreateSingleThreadTaskRunnerWithTraits(
158 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
159 SingleThreadTaskRunnerThreadMode::DEDICATED);
160
161 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread());
162 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread());
163
164 task_runner_1->PostTask(
165 FROM_HERE, BindOnce(
166 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1,
167 scoped_refptr<SingleThreadTaskRunner> task_runner_2) {
168 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread());
169 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread());
170 },
171 task_runner_1, task_runner_2));
172
173 task_runner_2->PostTask(
174 FROM_HERE, BindOnce(
175 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1,
176 scoped_refptr<SingleThreadTaskRunner> task_runner_2) {
177 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread());
178 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread());
179 },
180 task_runner_1, task_runner_2));
181
182 task_tracker_.Shutdown();
183 }
184
185 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest,
186 SharedWithBaseSyncPrimitivesDCHECKs) {
187 EXPECT_DCHECK_DEATH({
188 single_thread_task_runner_manager_->CreateSingleThreadTaskRunnerWithTraits(
189 "A", {WithBaseSyncPrimitives()},
190 SingleThreadTaskRunnerThreadMode::SHARED);
191 });
192 }
193
194 namespace {
195
196 class TaskSchedulerSingleThreadTaskRunnerManagerCommonTest
197 : public TaskSchedulerSingleThreadTaskRunnerManagerTest,
198 public ::testing::WithParamInterface<SingleThreadTaskRunnerThreadMode> {
199 public:
200 TaskSchedulerSingleThreadTaskRunnerManagerCommonTest() = default;
201
202 private:
203 DISALLOW_COPY_AND_ASSIGN(
204 TaskSchedulerSingleThreadTaskRunnerManagerCommonTest);
205 };
206
207 } // namespace
208
209 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest,
210 PrioritySetCorrectly) {
118 // Why are events used here instead of the task tracker? 211 // Why are events used here instead of the task tracker?
119 // Shutting down can cause priorities to get raised. This means we have to use 212 // Shutting down can cause priorities to get raised. This means we have to use
120 // events to determine when a task is run. 213 // events to determine when a task is run.
121 scoped_refptr<SingleThreadTaskRunner> task_runner_background = 214 scoped_refptr<SingleThreadTaskRunner> task_runner_background =
122 single_thread_task_runner_manager_ 215 single_thread_task_runner_manager_
123 ->CreateSingleThreadTaskRunnerWithTraits("Background", 216 ->CreateSingleThreadTaskRunnerWithTraits(
124 ThreadPriority::BACKGROUND, 217 "Background", {TaskPriority::BACKGROUND}, GetParam());
125 {TaskPriority::BACKGROUND});
126 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = 218 scoped_refptr<SingleThreadTaskRunner> task_runner_normal =
127 single_thread_task_runner_manager_ 219 single_thread_task_runner_manager_
128 ->CreateSingleThreadTaskRunnerWithTraits( 220 ->CreateSingleThreadTaskRunnerWithTraits(
129 "Normal", ThreadPriority::NORMAL, {TaskPriority::USER_VISIBLE}); 221 "Normal", {TaskPriority::USER_VISIBLE}, GetParam());
130 222
131 ThreadPriority thread_priority_background; 223 ThreadPriority thread_priority_background;
132 task_runner_background->PostTask( 224 task_runner_background->PostTask(
133 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); 225 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background));
134 WaitableEvent waitable_event_background( 226 WaitableEvent waitable_event_background(
135 WaitableEvent::ResetPolicy::MANUAL, 227 WaitableEvent::ResetPolicy::MANUAL,
136 WaitableEvent::InitialState::NOT_SIGNALED); 228 WaitableEvent::InitialState::NOT_SIGNALED);
137 task_runner_background->PostTask( 229 task_runner_background->PostTask(
138 FROM_HERE, 230 FROM_HERE,
139 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); 231 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background)));
(...skipping 11 matching lines...) Expand all
151 waitable_event_background.Wait(); 243 waitable_event_background.Wait();
152 waitable_event_normal.Wait(); 244 waitable_event_normal.Wait();
153 245
154 if (Lock::HandlesMultipleThreadPriorities()) 246 if (Lock::HandlesMultipleThreadPriorities())
155 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); 247 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background);
156 else 248 else
157 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); 249 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background);
158 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); 250 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal);
159 } 251 }
160 252
161 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { 253 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, ThreadNamesSet) {
254 constexpr TaskTraits foo_traits = {TaskPriority::BACKGROUND,
255 TaskShutdownBehavior::BLOCK_SHUTDOWN};
256 scoped_refptr<SingleThreadTaskRunner> foo_task_runner =
257 single_thread_task_runner_manager_
258 ->CreateSingleThreadTaskRunnerWithTraits("MyName", foo_traits,
259 GetParam());
260 std::string foo_captured_name;
261 foo_task_runner->PostTask(FROM_HERE,
262 BindOnce(&CaptureThreadName, &foo_captured_name));
263
264 constexpr TaskTraits user_blocking_traits = {
265 TaskPriority::USER_BLOCKING, MayBlock(),
266 TaskShutdownBehavior::BLOCK_SHUTDOWN};
267 scoped_refptr<SingleThreadTaskRunner> user_blocking_task_runner =
268 single_thread_task_runner_manager_
269 ->CreateSingleThreadTaskRunnerWithTraits("A", user_blocking_traits,
270 GetParam());
271
272 std::string user_blocking_captured_name;
273 user_blocking_task_runner->PostTask(
274 FROM_HERE, BindOnce(&CaptureThreadName, &user_blocking_captured_name));
275
276 task_tracker_.Shutdown();
277
278 EXPECT_NE(std::string::npos, foo_captured_name.find("MyName"));
279 EXPECT_NE(std::string::npos,
280 foo_captured_name.find(
281 kEnvironmentParams[GetEnvironmentIndexForTraits(foo_traits)]
282 .name_suffix));
283 EXPECT_NE(
284 std::string::npos,
285 user_blocking_captured_name.find(
286 kEnvironmentParams[GetEnvironmentIndexForTraits(user_blocking_traits)]
287 .name_suffix));
288
289 if (GetParam() == SingleThreadTaskRunnerThreadMode::DEDICATED) {
290 EXPECT_EQ(std::string::npos, foo_captured_name.find("Shared"));
291 EXPECT_EQ(std::string::npos, user_blocking_captured_name.find("Shared"));
292 } else {
293 EXPECT_NE(std::string::npos, foo_captured_name.find("Shared"));
294 EXPECT_NE(std::string::npos, user_blocking_captured_name.find("Shared"));
295 }
296 }
297
298 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest,
299 PostTaskAfterShutdown) {
162 auto task_runner = single_thread_task_runner_manager_ 300 auto task_runner = single_thread_task_runner_manager_
163 ->CreateSingleThreadTaskRunnerWithTraits( 301 ->CreateSingleThreadTaskRunnerWithTraits(
164 "A", ThreadPriority::NORMAL, TaskTraits()); 302 "A", TaskTraits(), GetParam());
165 task_tracker_.Shutdown(); 303 task_tracker_.Shutdown();
166 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); 304 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun)));
167 } 305 }
168 306
169 // Verify that a Task runs shortly after its delay expires. 307 // Verify that a Task runs shortly after its delay expires.
170 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { 308 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, PostDelayedTask) {
171 TimeTicks start_time = TimeTicks::Now(); 309 TimeTicks start_time = TimeTicks::Now();
172 310
173 // Post a task with a short delay. 311 // Post a task with a short delay.
174 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, 312 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
175 WaitableEvent::InitialState::NOT_SIGNALED); 313 WaitableEvent::InitialState::NOT_SIGNALED);
176 auto task_runner = single_thread_task_runner_manager_ 314 auto task_runner = single_thread_task_runner_manager_
177 ->CreateSingleThreadTaskRunnerWithTraits( 315 ->CreateSingleThreadTaskRunnerWithTraits(
178 "A", ThreadPriority::NORMAL, TaskTraits()); 316 "A", TaskTraits(), GetParam());
179 EXPECT_TRUE(task_runner->PostDelayedTask( 317 EXPECT_TRUE(task_runner->PostDelayedTask(
180 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), 318 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)),
181 TestTimeouts::tiny_timeout())); 319 TestTimeouts::tiny_timeout()));
182 320
183 // Wait until the task runs. 321 // Wait until the task runs.
184 task_ran.Wait(); 322 task_ran.Wait();
185 323
186 // Expect the task to run after its delay expires, but not more than 250 ms 324 // Expect the task to run after its delay expires, but not more than 250 ms
187 // after that. 325 // after that.
188 const TimeDelta actual_delay = TimeTicks::Now() - start_time; 326 const TimeDelta actual_delay = TimeTicks::Now() - start_time;
189 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); 327 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout());
190 EXPECT_LT(actual_delay, 328 EXPECT_LT(actual_delay,
191 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); 329 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout());
192 } 330 }
193 331
194 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, 332 INSTANTIATE_TEST_CASE_P(
195 RunsTasksOnCurrentThread) { 333 AllModes,
gab 2017/05/25 18:47:01 Should stay here as a Common test, no?
robliao 2017/05/30 20:01:07 See above.
196 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = 334 TaskSchedulerSingleThreadTaskRunnerManagerCommonTest,
197 single_thread_task_runner_manager_ 335 ::testing::Values(SingleThreadTaskRunnerThreadMode::SHARED,
198 ->CreateSingleThreadTaskRunnerWithTraits( 336 SingleThreadTaskRunnerThreadMode::DEDICATED));
199 "A", ThreadPriority::NORMAL,
200 {TaskShutdownBehavior::BLOCK_SHUTDOWN});
201 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
202 single_thread_task_runner_manager_
203 ->CreateSingleThreadTaskRunnerWithTraits(
204 "B", ThreadPriority::NORMAL,
205 {TaskShutdownBehavior::BLOCK_SHUTDOWN});
206
207 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread());
208 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread());
209
210 task_runner_1->PostTask(
211 FROM_HERE, BindOnce(
212 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1,
213 scoped_refptr<SingleThreadTaskRunner> task_runner_2) {
214 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread());
215 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread());
216 },
217 task_runner_1, task_runner_2));
218
219 task_runner_2->PostTask(
220 FROM_HERE, BindOnce(
221 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1,
222 scoped_refptr<SingleThreadTaskRunner> task_runner_2) {
223 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread());
224 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread());
225 },
226 task_runner_1, task_runner_2));
227
228 task_tracker_.Shutdown();
229 }
230 337
231 namespace { 338 namespace {
232 339
233 class CallJoinFromDifferentThread : public SimpleThread { 340 class CallJoinFromDifferentThread : public SimpleThread {
234 public: 341 public:
235 CallJoinFromDifferentThread( 342 CallJoinFromDifferentThread(
236 SchedulerSingleThreadTaskRunnerManager* manager_to_join) 343 SchedulerSingleThreadTaskRunnerManager* manager_to_join)
237 : SimpleThread("SchedulerSingleThreadTaskRunnerManagerJoinThread"), 344 : SimpleThread("SchedulerSingleThreadTaskRunnerManagerJoinThread"),
238 manager_to_join_(manager_to_join), 345 manager_to_join_(manager_to_join),
239 run_started_event_(WaitableEvent::ResetPolicy::MANUAL, 346 run_started_event_(WaitableEvent::ResetPolicy::MANUAL,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 382
276 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { 383 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) {
277 // Exercises the codepath where the workers are unavailable for unregistration 384 // Exercises the codepath where the workers are unavailable for unregistration
278 // because of a Join call. 385 // because of a Join call.
279 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, 386 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL,
280 WaitableEvent::InitialState::NOT_SIGNALED); 387 WaitableEvent::InitialState::NOT_SIGNALED);
281 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, 388 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL,
282 WaitableEvent::InitialState::NOT_SIGNALED); 389 WaitableEvent::InitialState::NOT_SIGNALED);
283 390
284 { 391 {
285 auto task_runner = 392 auto task_runner = single_thread_task_runner_manager_
286 single_thread_task_runner_manager_ 393 ->CreateSingleThreadTaskRunnerWithTraits(
287 ->CreateSingleThreadTaskRunnerWithTraits( 394 "A", {WithBaseSyncPrimitives()},
288 "A", ThreadPriority::NORMAL, {WithBaseSyncPrimitives()}); 395 SingleThreadTaskRunnerThreadMode::DEDICATED);
289 EXPECT_TRUE(task_runner->PostTask( 396 EXPECT_TRUE(task_runner->PostTask(
290 FROM_HERE, 397 FROM_HERE,
291 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); 398 BindOnce(&WaitableEvent::Signal, Unretained(&task_running))));
292 EXPECT_TRUE(task_runner->PostTask( 399 EXPECT_TRUE(task_runner->PostTask(
293 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); 400 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking))));
294 } 401 }
295 402
296 task_running.Wait(); 403 task_running.Wait();
297 CallJoinFromDifferentThread join_from_different_thread( 404 CallJoinFromDifferentThread join_from_different_thread(
298 single_thread_task_runner_manager_.get()); 405 single_thread_task_runner_manager_.get());
299 join_from_different_thread.Start(); 406 join_from_different_thread.Start();
300 join_from_different_thread.WaitForRunToStart(); 407 join_from_different_thread.WaitForRunToStart();
301 task_blocking.Signal(); 408 task_blocking.Signal();
302 join_from_different_thread.Join(); 409 join_from_different_thread.Join();
303 } 410 }
304 411
305 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, 412 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest,
306 ConcurrentJoinExtraSkippedTask) { 413 ConcurrentJoinExtraSkippedTask) {
307 // Tests to make sure that tasks are properly cleaned up at Join, allowing 414 // Tests to make sure that tasks are properly cleaned up at Join, allowing
308 // SingleThreadTaskRunners to unregister themselves. 415 // SingleThreadTaskRunners to unregister themselves.
309 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, 416 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL,
310 WaitableEvent::InitialState::NOT_SIGNALED); 417 WaitableEvent::InitialState::NOT_SIGNALED);
311 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, 418 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL,
312 WaitableEvent::InitialState::NOT_SIGNALED); 419 WaitableEvent::InitialState::NOT_SIGNALED);
313 420
314 { 421 {
315 auto task_runner = 422 auto task_runner = single_thread_task_runner_manager_
316 single_thread_task_runner_manager_ 423 ->CreateSingleThreadTaskRunnerWithTraits(
317 ->CreateSingleThreadTaskRunnerWithTraits( 424 "A", {WithBaseSyncPrimitives()},
318 "A", ThreadPriority::NORMAL, {WithBaseSyncPrimitives()}); 425 SingleThreadTaskRunnerThreadMode::DEDICATED);
319 EXPECT_TRUE(task_runner->PostTask( 426 EXPECT_TRUE(task_runner->PostTask(
320 FROM_HERE, 427 FROM_HERE,
321 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); 428 BindOnce(&WaitableEvent::Signal, Unretained(&task_running))));
322 EXPECT_TRUE(task_runner->PostTask( 429 EXPECT_TRUE(task_runner->PostTask(
323 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); 430 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking))));
324 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); 431 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)));
325 } 432 }
326 433
327 task_running.Wait(); 434 task_running.Wait();
328 CallJoinFromDifferentThread join_from_different_thread( 435 CallJoinFromDifferentThread join_from_different_thread(
329 single_thread_task_runner_manager_.get()); 436 single_thread_task_runner_manager_.get());
330 join_from_different_thread.Start(); 437 join_from_different_thread.Start();
331 join_from_different_thread.WaitForRunToStart(); 438 join_from_different_thread.WaitForRunToStart();
332 task_blocking.Signal(); 439 task_blocking.Signal();
333 join_from_different_thread.Join(); 440 join_from_different_thread.Join();
334 } 441 }
335 442
336 #if defined(OS_WIN) 443 #if defined(OS_WIN)
337 444
338 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { 445 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest,
446 COMSTAInitialized) {
339 scoped_refptr<SingleThreadTaskRunner> com_task_runner = 447 scoped_refptr<SingleThreadTaskRunner> com_task_runner =
340 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( 448 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits(
341 "A", ThreadPriority::NORMAL, {TaskShutdownBehavior::BLOCK_SHUTDOWN}); 449 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, GetParam());
342 450
343 com_task_runner->PostTask( 451 com_task_runner->PostTask(
344 FROM_HERE, BindOnce([]() { 452 FROM_HERE, BindOnce([]() {
345 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); 453 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
346 if (SUCCEEDED(hr)) { 454 if (SUCCEEDED(hr)) {
347 ADD_FAILURE() << "COM STA was not initialized on this thread"; 455 ADD_FAILURE() << "COM STA was not initialized on this thread";
348 CoUninitialize(); 456 CoUninitialize();
349 } 457 }
350 })); 458 }));
351 459
352 task_tracker_.Shutdown(); 460 task_tracker_.Shutdown();
353 } 461 }
354 462
463 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTASameThreadUsed) {
gab 2017/05/25 18:47:01 Seems like this is testing an implementation detai
robliao 2017/05/30 20:01:07 This is currently the only reasonable way to verif
464 scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
465 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits(
466 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
467 SingleThreadTaskRunnerThreadMode::SHARED);
468 scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
469 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits(
470 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
471 SingleThreadTaskRunnerThreadMode::SHARED);
472
473 PlatformThreadRef thread_ref_1;
474 task_runner_1->PostTask(FROM_HERE,
475 BindOnce(&CaptureThreadRef, &thread_ref_1));
476 PlatformThreadRef thread_ref_2;
477 task_runner_2->PostTask(FROM_HERE,
478 BindOnce(&CaptureThreadRef, &thread_ref_2));
479
480 task_tracker_.Shutdown();
481
482 ASSERT_FALSE(thread_ref_1.is_null());
483 ASSERT_FALSE(thread_ref_2.is_null());
484 EXPECT_EQ(thread_ref_1, thread_ref_2);
485 }
486
355 namespace { 487 namespace {
356 488
357 const wchar_t* const kTestWindowClassName = 489 const wchar_t* const kTestWindowClassName =
358 L"TaskSchedulerSingleThreadTaskRunnerManagerTestWinMessageWindow"; 490 L"TaskSchedulerSingleThreadTaskRunnerManagerTestWinMessageWindow";
359 491
360 class TaskSchedulerSingleThreadTaskRunnerManagerTestWin 492 class TaskSchedulerSingleThreadTaskRunnerManagerTestWin
361 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { 493 : public TaskSchedulerSingleThreadTaskRunnerManagerTest {
362 public: 494 public:
363 TaskSchedulerSingleThreadTaskRunnerManagerTestWin() = default; 495 TaskSchedulerSingleThreadTaskRunnerManagerTestWin() = default;
364 496
(...skipping 28 matching lines...) Expand all
393 bool register_class_succeeded_ = false; 525 bool register_class_succeeded_ = false;
394 526
395 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); 527 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin);
396 }; 528 };
397 529
398 } // namespace 530 } // namespace
399 531
400 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { 532 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) {
401 scoped_refptr<SingleThreadTaskRunner> com_task_runner = 533 scoped_refptr<SingleThreadTaskRunner> com_task_runner =
402 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( 534 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits(
403 "A", ThreadPriority::NORMAL, {TaskShutdownBehavior::BLOCK_SHUTDOWN}); 535 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN},
536 SingleThreadTaskRunnerThreadMode::DEDICATED);
gab 2017/05/25 18:47:01 Why isn't this also Common?
robliao 2017/05/30 20:01:07 This uses TaskSchedulerSingleThreadTaskRunnerTestW
404 HWND hwnd = nullptr; 537 HWND hwnd = nullptr;
405 // HWNDs process messages on the thread that created them, so we have to 538 // HWNDs process messages on the thread that created them, so we have to
406 // create them within the context of the task runner to properly simulate a 539 // create them within the context of the task runner to properly simulate a
407 // COM callback. 540 // COM callback.
408 com_task_runner->PostTask( 541 com_task_runner->PostTask(
409 FROM_HERE, 542 FROM_HERE,
410 BindOnce( 543 BindOnce(
411 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, 544 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness,
412 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, 545 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); },
413 Unretained(this), &hwnd)); 546 Unretained(this), &hwnd));
(...skipping 25 matching lines...) Expand all
439 // Start() is called in the test body rather than in SetUp(). 572 // Start() is called in the test body rather than in SetUp().
440 } 573 }
441 574
442 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerStartTest); 575 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerStartTest);
443 }; 576 };
444 577
445 } // namespace 578 } // namespace
446 579
447 // Verify that a task posted before Start() doesn't run until Start() is called. 580 // Verify that a task posted before Start() doesn't run until Start() is called.
448 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, 581 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest,
449 PostTaskBeforeStart) { 582 PostTaskBeforeStart) {
gab 2017/05/25 18:47:01 Why isn't this also Common?
robliao 2017/05/30 20:01:07 See above. This is a different class similar to th
450 AtomicFlag manager_started; 583 AtomicFlag manager_started;
451 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, 584 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL,
452 WaitableEvent::InitialState::NOT_SIGNALED); 585 WaitableEvent::InitialState::NOT_SIGNALED);
453 single_thread_task_runner_manager_ 586 single_thread_task_runner_manager_
454 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, 587 ->CreateSingleThreadTaskRunnerWithTraits(
455 TaskTraits()) 588 "A", TaskTraits(), SingleThreadTaskRunnerThreadMode::DEDICATED)
456 ->PostTask( 589 ->PostTask(
457 FROM_HERE, 590 FROM_HERE,
458 BindOnce( 591 BindOnce(
459 [](WaitableEvent* task_running, AtomicFlag* manager_started) { 592 [](WaitableEvent* task_running, AtomicFlag* manager_started) {
460 task_running->Signal(); 593 task_running->Signal();
461 594
462 // The task should not run before Start(). 595 // The task should not run before Start().
463 EXPECT_TRUE(manager_started->IsSet()); 596 EXPECT_TRUE(manager_started->IsSet());
464 }, 597 },
465 Unretained(&task_running), Unretained(&manager_started))); 598 Unretained(&task_running), Unretained(&manager_started)));
466 599
467 // Wait a little bit to make sure that the task isn't scheduled before start. 600 // Wait a little bit to make sure that the task isn't scheduled before start.
468 // Note: This test won't catch a case where the task is scheduled between 601 // Note: This test won't catch a case where the task is scheduled between
469 // setting |manager_started| and calling Start(). However, we expect the test 602 // setting |manager_started| and calling Start(). However, we expect the test
470 // to be flaky if the tested code allows that to happen. 603 // to be flaky if the tested code allows that to happen.
471 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); 604 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
472 manager_started.Set(); 605 manager_started.Set();
473 single_thread_task_runner_manager_->Start(); 606 single_thread_task_runner_manager_->Start();
474 607
475 // This should not hang if the task is scheduled after Start(). 608 // This should not hang if the task is scheduled after Start().
476 task_running.Wait(); 609 task_running.Wait();
477 } 610 }
478 611
479 } // namespace internal 612 } // namespace internal
480 } // namespace base 613 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698