| 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" |
| 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/task_scheduler/test_utils.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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 ADD_FAILURE() << "Ran a task that shouldn't run."; | 87 ADD_FAILURE() << "Ran a task that shouldn't run."; |
| 87 } | 88 } |
| 88 | 89 |
| 89 } // namespace | 90 } // namespace |
| 90 | 91 |
| 91 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 92 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { |
| 92 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 93 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
| 93 single_thread_task_runner_manager_ | 94 single_thread_task_runner_manager_ |
| 94 ->CreateSingleThreadTaskRunnerWithTraits( | 95 ->CreateSingleThreadTaskRunnerWithTraits( |
| 95 "A", ThreadPriority::NORMAL, | 96 "A", ThreadPriority::NORMAL, |
| 96 TaskTraits().WithShutdownBehavior( | 97 test::CreateTaskTraits().WithShutdownBehavior( |
| 97 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 98 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 98 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 99 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
| 99 single_thread_task_runner_manager_ | 100 single_thread_task_runner_manager_ |
| 100 ->CreateSingleThreadTaskRunnerWithTraits( | 101 ->CreateSingleThreadTaskRunnerWithTraits( |
| 101 "B", ThreadPriority::NORMAL, | 102 "B", ThreadPriority::NORMAL, |
| 102 TaskTraits().WithShutdownBehavior( | 103 test::CreateTaskTraits().WithShutdownBehavior( |
| 103 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 104 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 104 | 105 |
| 105 PlatformThreadRef thread_ref_1; | 106 PlatformThreadRef thread_ref_1; |
| 106 task_runner_1->PostTask(FROM_HERE, | 107 task_runner_1->PostTask(FROM_HERE, |
| 107 BindOnce(&CaptureThreadRef, &thread_ref_1)); | 108 BindOnce(&CaptureThreadRef, &thread_ref_1)); |
| 108 PlatformThreadRef thread_ref_2; | 109 PlatformThreadRef thread_ref_2; |
| 109 task_runner_2->PostTask(FROM_HERE, | 110 task_runner_2->PostTask(FROM_HERE, |
| 110 BindOnce(&CaptureThreadRef, &thread_ref_2)); | 111 BindOnce(&CaptureThreadRef, &thread_ref_2)); |
| 111 | 112 |
| 112 task_tracker_.Shutdown(); | 113 task_tracker_.Shutdown(); |
| 113 | 114 |
| 114 ASSERT_FALSE(thread_ref_1.is_null()); | 115 ASSERT_FALSE(thread_ref_1.is_null()); |
| 115 ASSERT_FALSE(thread_ref_2.is_null()); | 116 ASSERT_FALSE(thread_ref_2.is_null()); |
| 116 EXPECT_NE(thread_ref_1, thread_ref_2); | 117 EXPECT_NE(thread_ref_1, thread_ref_2); |
| 117 } | 118 } |
| 118 | 119 |
| 119 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 120 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { |
| 120 // Why are events used here instead of the task tracker? | 121 // 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 | 122 // Shutting down can cause priorities to get raised. This means we have to use |
| 122 // events to determine when a task is run. | 123 // events to determine when a task is run. |
| 123 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 124 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
| 124 single_thread_task_runner_manager_ | 125 single_thread_task_runner_manager_ |
| 125 ->CreateSingleThreadTaskRunnerWithTraits( | 126 ->CreateSingleThreadTaskRunnerWithTraits( |
| 126 "Background", ThreadPriority::BACKGROUND, | 127 "Background", ThreadPriority::BACKGROUND, |
| 127 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 128 test::CreateTaskTraits().WithPriority(TaskPriority::BACKGROUND)); |
| 128 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = | 129 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = |
| 129 single_thread_task_runner_manager_ | 130 single_thread_task_runner_manager_ |
| 130 ->CreateSingleThreadTaskRunnerWithTraits( | 131 ->CreateSingleThreadTaskRunnerWithTraits( |
| 131 "Normal", ThreadPriority::NORMAL, | 132 "Normal", ThreadPriority::NORMAL, |
| 132 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | 133 test::CreateTaskTraits().WithPriority( |
| 134 TaskPriority::USER_VISIBLE)); |
| 133 | 135 |
| 134 ThreadPriority thread_priority_background; | 136 ThreadPriority thread_priority_background; |
| 135 task_runner_background->PostTask( | 137 task_runner_background->PostTask( |
| 136 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); | 138 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); |
| 137 WaitableEvent waitable_event_background( | 139 WaitableEvent waitable_event_background( |
| 138 WaitableEvent::ResetPolicy::MANUAL, | 140 WaitableEvent::ResetPolicy::MANUAL, |
| 139 WaitableEvent::InitialState::NOT_SIGNALED); | 141 WaitableEvent::InitialState::NOT_SIGNALED); |
| 140 task_runner_background->PostTask( | 142 task_runner_background->PostTask( |
| 141 FROM_HERE, | 143 FROM_HERE, |
| 142 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 144 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 155 waitable_event_normal.Wait(); | 157 waitable_event_normal.Wait(); |
| 156 | 158 |
| 157 if (Lock::HandlesMultipleThreadPriorities()) | 159 if (Lock::HandlesMultipleThreadPriorities()) |
| 158 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 160 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); |
| 159 else | 161 else |
| 160 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 162 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); |
| 161 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); | 163 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); |
| 162 } | 164 } |
| 163 | 165 |
| 164 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 166 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { |
| 165 auto task_runner = single_thread_task_runner_manager_ | 167 auto task_runner = |
| 166 ->CreateSingleThreadTaskRunnerWithTraits( | 168 single_thread_task_runner_manager_ |
| 167 "A", ThreadPriority::NORMAL, TaskTraits()); | 169 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, |
| 170 test::CreateTaskTraits()); |
| 168 task_tracker_.Shutdown(); | 171 task_tracker_.Shutdown(); |
| 169 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); | 172 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); |
| 170 } | 173 } |
| 171 | 174 |
| 172 // Verify that a Task runs shortly after its delay expires. | 175 // Verify that a Task runs shortly after its delay expires. |
| 173 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 176 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { |
| 174 TimeTicks start_time = TimeTicks::Now(); | 177 TimeTicks start_time = TimeTicks::Now(); |
| 175 | 178 |
| 176 // Post a task with a short delay. | 179 // Post a task with a short delay. |
| 177 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 180 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
| 178 WaitableEvent::InitialState::NOT_SIGNALED); | 181 WaitableEvent::InitialState::NOT_SIGNALED); |
| 179 auto task_runner = single_thread_task_runner_manager_ | 182 auto task_runner = |
| 180 ->CreateSingleThreadTaskRunnerWithTraits( | 183 single_thread_task_runner_manager_ |
| 181 "A", ThreadPriority::NORMAL, TaskTraits()); | 184 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, |
| 185 test::CreateTaskTraits()); |
| 182 EXPECT_TRUE(task_runner->PostDelayedTask( | 186 EXPECT_TRUE(task_runner->PostDelayedTask( |
| 183 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), | 187 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), |
| 184 TestTimeouts::tiny_timeout())); | 188 TestTimeouts::tiny_timeout())); |
| 185 | 189 |
| 186 // Wait until the task runs. | 190 // Wait until the task runs. |
| 187 task_ran.Wait(); | 191 task_ran.Wait(); |
| 188 | 192 |
| 189 // Expect the task to run after its delay expires, but not more than 250 ms | 193 // Expect the task to run after its delay expires, but not more than 250 ms |
| 190 // after that. | 194 // after that. |
| 191 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 195 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
| 192 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 196 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
| 193 EXPECT_LT(actual_delay, | 197 EXPECT_LT(actual_delay, |
| 194 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 198 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
| 195 } | 199 } |
| 196 | 200 |
| 197 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 201 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, |
| 198 RunsTasksOnCurrentThread) { | 202 RunsTasksOnCurrentThread) { |
| 199 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 203 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
| 200 single_thread_task_runner_manager_ | 204 single_thread_task_runner_manager_ |
| 201 ->CreateSingleThreadTaskRunnerWithTraits( | 205 ->CreateSingleThreadTaskRunnerWithTraits( |
| 202 "A", ThreadPriority::NORMAL, | 206 "A", ThreadPriority::NORMAL, |
| 203 TaskTraits().WithShutdownBehavior( | 207 test::CreateTaskTraits().WithShutdownBehavior( |
| 204 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 208 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 205 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 209 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
| 206 single_thread_task_runner_manager_ | 210 single_thread_task_runner_manager_ |
| 207 ->CreateSingleThreadTaskRunnerWithTraits( | 211 ->CreateSingleThreadTaskRunnerWithTraits( |
| 208 "B", ThreadPriority::NORMAL, | 212 "B", ThreadPriority::NORMAL, |
| 209 TaskTraits().WithShutdownBehavior( | 213 test::CreateTaskTraits().WithShutdownBehavior( |
| 210 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 214 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 211 | 215 |
| 212 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 216 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); |
| 213 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 217 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
| 214 | 218 |
| 215 task_runner_1->PostTask( | 219 task_runner_1->PostTask( |
| 216 FROM_HERE, BindOnce( | 220 FROM_HERE, BindOnce( |
| 217 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 221 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, |
| 218 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 222 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { |
| 219 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); | 223 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 | 284 |
| 281 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { | 285 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { |
| 282 // Exercises the codepath where the workers are unavailable for unregistration | 286 // Exercises the codepath where the workers are unavailable for unregistration |
| 283 // because of a Join call. | 287 // because of a Join call. |
| 284 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 288 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 285 WaitableEvent::InitialState::NOT_SIGNALED); | 289 WaitableEvent::InitialState::NOT_SIGNALED); |
| 286 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 290 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
| 287 WaitableEvent::InitialState::NOT_SIGNALED); | 291 WaitableEvent::InitialState::NOT_SIGNALED); |
| 288 | 292 |
| 289 { | 293 { |
| 290 auto task_runner = single_thread_task_runner_manager_ | 294 auto task_runner = |
| 291 ->CreateSingleThreadTaskRunnerWithTraits( | 295 single_thread_task_runner_manager_ |
| 292 "A", ThreadPriority::NORMAL, | 296 ->CreateSingleThreadTaskRunnerWithTraits( |
| 293 TaskTraits().WithBaseSyncPrimitives()); | 297 "A", ThreadPriority::NORMAL, |
| 298 test::CreateTaskTraits().WithBaseSyncPrimitives()); |
| 294 EXPECT_TRUE(task_runner->PostTask( | 299 EXPECT_TRUE(task_runner->PostTask( |
| 295 FROM_HERE, | 300 FROM_HERE, |
| 296 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 301 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
| 297 EXPECT_TRUE(task_runner->PostTask( | 302 EXPECT_TRUE(task_runner->PostTask( |
| 298 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 303 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
| 299 } | 304 } |
| 300 | 305 |
| 301 task_running.Wait(); | 306 task_running.Wait(); |
| 302 CallJoinFromDifferentThread join_from_different_thread( | 307 CallJoinFromDifferentThread join_from_different_thread( |
| 303 single_thread_task_runner_manager_.get()); | 308 single_thread_task_runner_manager_.get()); |
| 304 join_from_different_thread.Start(); | 309 join_from_different_thread.Start(); |
| 305 join_from_different_thread.WaitForRunToStart(); | 310 join_from_different_thread.WaitForRunToStart(); |
| 306 task_blocking.Signal(); | 311 task_blocking.Signal(); |
| 307 join_from_different_thread.Join(); | 312 join_from_different_thread.Join(); |
| 308 } | 313 } |
| 309 | 314 |
| 310 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 315 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
| 311 ConcurrentJoinExtraSkippedTask) { | 316 ConcurrentJoinExtraSkippedTask) { |
| 312 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 317 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
| 313 // SingleThreadTaskRunners to unregister themselves. | 318 // SingleThreadTaskRunners to unregister themselves. |
| 314 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 319 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 315 WaitableEvent::InitialState::NOT_SIGNALED); | 320 WaitableEvent::InitialState::NOT_SIGNALED); |
| 316 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 321 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
| 317 WaitableEvent::InitialState::NOT_SIGNALED); | 322 WaitableEvent::InitialState::NOT_SIGNALED); |
| 318 | 323 |
| 319 { | 324 { |
| 320 auto task_runner = single_thread_task_runner_manager_ | 325 auto task_runner = |
| 321 ->CreateSingleThreadTaskRunnerWithTraits( | 326 single_thread_task_runner_manager_ |
| 322 "A", ThreadPriority::NORMAL, | 327 ->CreateSingleThreadTaskRunnerWithTraits( |
| 323 TaskTraits().WithBaseSyncPrimitives()); | 328 "A", ThreadPriority::NORMAL, |
| 329 test::CreateTaskTraits().WithBaseSyncPrimitives()); |
| 324 EXPECT_TRUE(task_runner->PostTask( | 330 EXPECT_TRUE(task_runner->PostTask( |
| 325 FROM_HERE, | 331 FROM_HERE, |
| 326 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 332 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
| 327 EXPECT_TRUE(task_runner->PostTask( | 333 EXPECT_TRUE(task_runner->PostTask( |
| 328 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 334 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
| 329 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); | 335 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); |
| 330 } | 336 } |
| 331 | 337 |
| 332 task_running.Wait(); | 338 task_running.Wait(); |
| 333 CallJoinFromDifferentThread join_from_different_thread( | 339 CallJoinFromDifferentThread join_from_different_thread( |
| 334 single_thread_task_runner_manager_.get()); | 340 single_thread_task_runner_manager_.get()); |
| 335 join_from_different_thread.Start(); | 341 join_from_different_thread.Start(); |
| 336 join_from_different_thread.WaitForRunToStart(); | 342 join_from_different_thread.WaitForRunToStart(); |
| 337 task_blocking.Signal(); | 343 task_blocking.Signal(); |
| 338 join_from_different_thread.Join(); | 344 join_from_different_thread.Join(); |
| 339 } | 345 } |
| 340 | 346 |
| 341 #if defined(OS_WIN) | 347 #if defined(OS_WIN) |
| 342 | 348 |
| 343 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 349 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { |
| 344 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 350 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
| 345 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 351 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 346 "A", ThreadPriority::NORMAL, | 352 "A", ThreadPriority::NORMAL, |
| 347 TaskTraits().WithShutdownBehavior( | 353 test::CreateTaskTraits().WithShutdownBehavior( |
| 348 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 354 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 349 | 355 |
| 350 com_task_runner->PostTask( | 356 com_task_runner->PostTask( |
| 351 FROM_HERE, BindOnce([]() { | 357 FROM_HERE, BindOnce([]() { |
| 352 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 358 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
| 353 if (SUCCEEDED(hr)) { | 359 if (SUCCEEDED(hr)) { |
| 354 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 360 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
| 355 CoUninitialize(); | 361 CoUninitialize(); |
| 356 } | 362 } |
| 357 })); | 363 })); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 | 407 |
| 402 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 408 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); |
| 403 }; | 409 }; |
| 404 | 410 |
| 405 } // namespace | 411 } // namespace |
| 406 | 412 |
| 407 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 413 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { |
| 408 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 414 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
| 409 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 415 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 410 "A", ThreadPriority::NORMAL, | 416 "A", ThreadPriority::NORMAL, |
| 411 TaskTraits().WithShutdownBehavior( | 417 test::CreateTaskTraits().WithShutdownBehavior( |
| 412 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 418 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 413 HWND hwnd = nullptr; | 419 HWND hwnd = nullptr; |
| 414 // HWNDs process messages on the thread that created them, so we have to | 420 // 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 | 421 // create them within the context of the task runner to properly simulate a |
| 416 // COM callback. | 422 // COM callback. |
| 417 com_task_runner->PostTask( | 423 com_task_runner->PostTask( |
| 418 FROM_HERE, | 424 FROM_HERE, |
| 419 BindOnce( | 425 BindOnce( |
| 420 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 426 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, |
| 421 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 427 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 } // namespace | 460 } // namespace |
| 455 | 461 |
| 456 // Verify that a task posted before Start() doesn't run until Start() is called. | 462 // Verify that a task posted before Start() doesn't run until Start() is called. |
| 457 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, | 463 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, |
| 458 PostTaskBeforeStart) { | 464 PostTaskBeforeStart) { |
| 459 AtomicFlag manager_started; | 465 AtomicFlag manager_started; |
| 460 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 466 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 461 WaitableEvent::InitialState::NOT_SIGNALED); | 467 WaitableEvent::InitialState::NOT_SIGNALED); |
| 462 single_thread_task_runner_manager_ | 468 single_thread_task_runner_manager_ |
| 463 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, | 469 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, |
| 464 TaskTraits()) | 470 test::CreateTaskTraits()) |
| 465 ->PostTask( | 471 ->PostTask( |
| 466 FROM_HERE, | 472 FROM_HERE, |
| 467 BindOnce( | 473 BindOnce( |
| 468 [](WaitableEvent* task_running, AtomicFlag* manager_started) { | 474 [](WaitableEvent* task_running, AtomicFlag* manager_started) { |
| 469 task_running->Signal(); | 475 task_running->Signal(); |
| 470 | 476 |
| 471 // The task should not run before Start(). | 477 // The task should not run before Start(). |
| 472 EXPECT_TRUE(manager_started->IsSet()); | 478 EXPECT_TRUE(manager_started->IsSet()); |
| 473 }, | 479 }, |
| 474 Unretained(&task_running), Unretained(&manager_started))); | 480 Unretained(&task_running), Unretained(&manager_started))); |
| 475 | 481 |
| 476 // Wait a little bit to make sure that the task isn't scheduled before start. | 482 // Wait a little bit to make sure that the task isn't scheduled before start. |
| 477 // Note: This test won't catch a case where the task is scheduled between | 483 // Note: This test won't catch a case where the task is scheduled between |
| 478 // setting |manager_started| and calling Start(). However, we expect the test | 484 // setting |manager_started| and calling Start(). However, we expect the test |
| 479 // to be flaky if the tested code allows that to happen. | 485 // to be flaky if the tested code allows that to happen. |
| 480 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 486 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 481 manager_started.Set(); | 487 manager_started.Set(); |
| 482 single_thread_task_runner_manager_->Start(); | 488 single_thread_task_runner_manager_->Start(); |
| 483 | 489 |
| 484 // This should not hang if the task is scheduled after Start(). | 490 // This should not hang if the task is scheduled after Start(). |
| 485 task_running.Wait(); | 491 task_running.Wait(); |
| 486 } | 492 } |
| 487 | 493 |
| 488 } // namespace internal | 494 } // namespace internal |
| 489 } // namespace base | 495 } // namespace base |
| OLD | NEW |