OLD | NEW |
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" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 ADD_FAILURE() << "Ran a task that shouldn't run."; | 86 ADD_FAILURE() << "Ran a task that shouldn't run."; |
87 } | 87 } |
88 | 88 |
89 } // namespace | 89 } // namespace |
90 | 90 |
91 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 91 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { |
92 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 92 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
93 single_thread_task_runner_manager_ | 93 single_thread_task_runner_manager_ |
94 ->CreateSingleThreadTaskRunnerWithTraits( | 94 ->CreateSingleThreadTaskRunnerWithTraits( |
95 "A", ThreadPriority::NORMAL, | 95 "A", ThreadPriority::NORMAL, |
96 TaskTraits().WithShutdownBehavior( | 96 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
97 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
98 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 97 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
99 single_thread_task_runner_manager_ | 98 single_thread_task_runner_manager_ |
100 ->CreateSingleThreadTaskRunnerWithTraits( | 99 ->CreateSingleThreadTaskRunnerWithTraits( |
101 "B", ThreadPriority::NORMAL, | 100 "B", ThreadPriority::NORMAL, |
102 TaskTraits().WithShutdownBehavior( | 101 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
103 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
104 | 102 |
105 PlatformThreadRef thread_ref_1; | 103 PlatformThreadRef thread_ref_1; |
106 task_runner_1->PostTask(FROM_HERE, | 104 task_runner_1->PostTask(FROM_HERE, |
107 BindOnce(&CaptureThreadRef, &thread_ref_1)); | 105 BindOnce(&CaptureThreadRef, &thread_ref_1)); |
108 PlatformThreadRef thread_ref_2; | 106 PlatformThreadRef thread_ref_2; |
109 task_runner_2->PostTask(FROM_HERE, | 107 task_runner_2->PostTask(FROM_HERE, |
110 BindOnce(&CaptureThreadRef, &thread_ref_2)); | 108 BindOnce(&CaptureThreadRef, &thread_ref_2)); |
111 | 109 |
112 task_tracker_.Shutdown(); | 110 task_tracker_.Shutdown(); |
113 | 111 |
114 ASSERT_FALSE(thread_ref_1.is_null()); | 112 ASSERT_FALSE(thread_ref_1.is_null()); |
115 ASSERT_FALSE(thread_ref_2.is_null()); | 113 ASSERT_FALSE(thread_ref_2.is_null()); |
116 EXPECT_NE(thread_ref_1, thread_ref_2); | 114 EXPECT_NE(thread_ref_1, thread_ref_2); |
117 } | 115 } |
118 | 116 |
119 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 117 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { |
120 // Why are events used here instead of the task tracker? | 118 // Why are events used here instead of the task tracker? |
121 // Shutting down can cause priorities to get raised. This means we have to use | 119 // Shutting down can cause priorities to get raised. This means we have to use |
122 // events to determine when a task is run. | 120 // events to determine when a task is run. |
123 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 121 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
124 single_thread_task_runner_manager_ | 122 single_thread_task_runner_manager_ |
125 ->CreateSingleThreadTaskRunnerWithTraits( | 123 ->CreateSingleThreadTaskRunnerWithTraits("Background", |
126 "Background", ThreadPriority::BACKGROUND, | 124 ThreadPriority::BACKGROUND, |
127 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 125 {TaskPriority::BACKGROUND}); |
128 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = | 126 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = |
129 single_thread_task_runner_manager_ | 127 single_thread_task_runner_manager_ |
130 ->CreateSingleThreadTaskRunnerWithTraits( | 128 ->CreateSingleThreadTaskRunnerWithTraits( |
131 "Normal", ThreadPriority::NORMAL, | 129 "Normal", ThreadPriority::NORMAL, {TaskPriority::USER_VISIBLE}); |
132 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | |
133 | 130 |
134 ThreadPriority thread_priority_background; | 131 ThreadPriority thread_priority_background; |
135 task_runner_background->PostTask( | 132 task_runner_background->PostTask( |
136 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); | 133 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); |
137 WaitableEvent waitable_event_background( | 134 WaitableEvent waitable_event_background( |
138 WaitableEvent::ResetPolicy::MANUAL, | 135 WaitableEvent::ResetPolicy::MANUAL, |
139 WaitableEvent::InitialState::NOT_SIGNALED); | 136 WaitableEvent::InitialState::NOT_SIGNALED); |
140 task_runner_background->PostTask( | 137 task_runner_background->PostTask( |
141 FROM_HERE, | 138 FROM_HERE, |
142 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 139 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 EXPECT_LT(actual_delay, | 190 EXPECT_LT(actual_delay, |
194 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 191 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
195 } | 192 } |
196 | 193 |
197 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 194 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, |
198 RunsTasksOnCurrentThread) { | 195 RunsTasksOnCurrentThread) { |
199 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 196 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
200 single_thread_task_runner_manager_ | 197 single_thread_task_runner_manager_ |
201 ->CreateSingleThreadTaskRunnerWithTraits( | 198 ->CreateSingleThreadTaskRunnerWithTraits( |
202 "A", ThreadPriority::NORMAL, | 199 "A", ThreadPriority::NORMAL, |
203 TaskTraits().WithShutdownBehavior( | 200 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
204 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
205 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 201 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
206 single_thread_task_runner_manager_ | 202 single_thread_task_runner_manager_ |
207 ->CreateSingleThreadTaskRunnerWithTraits( | 203 ->CreateSingleThreadTaskRunnerWithTraits( |
208 "B", ThreadPriority::NORMAL, | 204 "B", ThreadPriority::NORMAL, |
209 TaskTraits().WithShutdownBehavior( | 205 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
210 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
211 | 206 |
212 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 207 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); |
213 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 208 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
214 | 209 |
215 task_runner_1->PostTask( | 210 task_runner_1->PostTask( |
216 FROM_HERE, BindOnce( | 211 FROM_HERE, BindOnce( |
217 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 212 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, |
218 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 213 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { |
219 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); | 214 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); |
220 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 215 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 | 275 |
281 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { | 276 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { |
282 // Exercises the codepath where the workers are unavailable for unregistration | 277 // Exercises the codepath where the workers are unavailable for unregistration |
283 // because of a Join call. | 278 // because of a Join call. |
284 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 279 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
285 WaitableEvent::InitialState::NOT_SIGNALED); | 280 WaitableEvent::InitialState::NOT_SIGNALED); |
286 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 281 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
287 WaitableEvent::InitialState::NOT_SIGNALED); | 282 WaitableEvent::InitialState::NOT_SIGNALED); |
288 | 283 |
289 { | 284 { |
290 auto task_runner = single_thread_task_runner_manager_ | 285 auto task_runner = |
291 ->CreateSingleThreadTaskRunnerWithTraits( | 286 single_thread_task_runner_manager_ |
292 "A", ThreadPriority::NORMAL, | 287 ->CreateSingleThreadTaskRunnerWithTraits( |
293 TaskTraits().WithBaseSyncPrimitives()); | 288 "A", ThreadPriority::NORMAL, {WithBaseSyncPrimitives()}); |
294 EXPECT_TRUE(task_runner->PostTask( | 289 EXPECT_TRUE(task_runner->PostTask( |
295 FROM_HERE, | 290 FROM_HERE, |
296 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 291 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
297 EXPECT_TRUE(task_runner->PostTask( | 292 EXPECT_TRUE(task_runner->PostTask( |
298 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 293 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
299 } | 294 } |
300 | 295 |
301 task_running.Wait(); | 296 task_running.Wait(); |
302 CallJoinFromDifferentThread join_from_different_thread( | 297 CallJoinFromDifferentThread join_from_different_thread( |
303 single_thread_task_runner_manager_.get()); | 298 single_thread_task_runner_manager_.get()); |
304 join_from_different_thread.Start(); | 299 join_from_different_thread.Start(); |
305 join_from_different_thread.WaitForRunToStart(); | 300 join_from_different_thread.WaitForRunToStart(); |
306 task_blocking.Signal(); | 301 task_blocking.Signal(); |
307 join_from_different_thread.Join(); | 302 join_from_different_thread.Join(); |
308 } | 303 } |
309 | 304 |
310 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 305 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
311 ConcurrentJoinExtraSkippedTask) { | 306 ConcurrentJoinExtraSkippedTask) { |
312 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 307 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
313 // SingleThreadTaskRunners to unregister themselves. | 308 // SingleThreadTaskRunners to unregister themselves. |
314 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 309 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
315 WaitableEvent::InitialState::NOT_SIGNALED); | 310 WaitableEvent::InitialState::NOT_SIGNALED); |
316 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 311 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
317 WaitableEvent::InitialState::NOT_SIGNALED); | 312 WaitableEvent::InitialState::NOT_SIGNALED); |
318 | 313 |
319 { | 314 { |
320 auto task_runner = single_thread_task_runner_manager_ | 315 auto task_runner = |
321 ->CreateSingleThreadTaskRunnerWithTraits( | 316 single_thread_task_runner_manager_ |
322 "A", ThreadPriority::NORMAL, | 317 ->CreateSingleThreadTaskRunnerWithTraits( |
323 TaskTraits().WithBaseSyncPrimitives()); | 318 "A", ThreadPriority::NORMAL, {WithBaseSyncPrimitives()}); |
324 EXPECT_TRUE(task_runner->PostTask( | 319 EXPECT_TRUE(task_runner->PostTask( |
325 FROM_HERE, | 320 FROM_HERE, |
326 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 321 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
327 EXPECT_TRUE(task_runner->PostTask( | 322 EXPECT_TRUE(task_runner->PostTask( |
328 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 323 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
329 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); | 324 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); |
330 } | 325 } |
331 | 326 |
332 task_running.Wait(); | 327 task_running.Wait(); |
333 CallJoinFromDifferentThread join_from_different_thread( | 328 CallJoinFromDifferentThread join_from_different_thread( |
334 single_thread_task_runner_manager_.get()); | 329 single_thread_task_runner_manager_.get()); |
335 join_from_different_thread.Start(); | 330 join_from_different_thread.Start(); |
336 join_from_different_thread.WaitForRunToStart(); | 331 join_from_different_thread.WaitForRunToStart(); |
337 task_blocking.Signal(); | 332 task_blocking.Signal(); |
338 join_from_different_thread.Join(); | 333 join_from_different_thread.Join(); |
339 } | 334 } |
340 | 335 |
341 #if defined(OS_WIN) | 336 #if defined(OS_WIN) |
342 | 337 |
343 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 338 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { |
344 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 339 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
345 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 340 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
346 "A", ThreadPriority::NORMAL, | 341 "A", ThreadPriority::NORMAL, {TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
347 TaskTraits().WithShutdownBehavior( | |
348 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
349 | 342 |
350 com_task_runner->PostTask( | 343 com_task_runner->PostTask( |
351 FROM_HERE, BindOnce([]() { | 344 FROM_HERE, BindOnce([]() { |
352 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 345 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
353 if (SUCCEEDED(hr)) { | 346 if (SUCCEEDED(hr)) { |
354 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 347 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
355 CoUninitialize(); | 348 CoUninitialize(); |
356 } | 349 } |
357 })); | 350 })); |
358 | 351 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 bool register_class_succeeded_ = false; | 393 bool register_class_succeeded_ = false; |
401 | 394 |
402 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 395 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); |
403 }; | 396 }; |
404 | 397 |
405 } // namespace | 398 } // namespace |
406 | 399 |
407 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 400 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { |
408 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 401 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
409 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 402 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
410 "A", ThreadPriority::NORMAL, | 403 "A", ThreadPriority::NORMAL, {TaskShutdownBehavior::BLOCK_SHUTDOWN}); |
411 TaskTraits().WithShutdownBehavior( | |
412 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
413 HWND hwnd = nullptr; | 404 HWND hwnd = nullptr; |
414 // HWNDs process messages on the thread that created them, so we have to | 405 // HWNDs process messages on the thread that created them, so we have to |
415 // create them within the context of the task runner to properly simulate a | 406 // create them within the context of the task runner to properly simulate a |
416 // COM callback. | 407 // COM callback. |
417 com_task_runner->PostTask( | 408 com_task_runner->PostTask( |
418 FROM_HERE, | 409 FROM_HERE, |
419 BindOnce( | 410 BindOnce( |
420 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 411 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, |
421 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 412 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, |
422 Unretained(this), &hwnd)); | 413 Unretained(this), &hwnd)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 471 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
481 manager_started.Set(); | 472 manager_started.Set(); |
482 single_thread_task_runner_manager_->Start(); | 473 single_thread_task_runner_manager_->Start(); |
483 | 474 |
484 // This should not hang if the task is scheduled after Start(). | 475 // This should not hang if the task is scheduled after Start(). |
485 task_running.Wait(); | 476 task_running.Wait(); |
486 } | 477 } |
487 | 478 |
488 } // namespace internal | 479 } // namespace internal |
489 } // namespace base | 480 } // namespace base |
OLD | NEW |