Chromium Code Reviews| 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 14 matching lines...) Expand all Loading... | |
| 25 #include <objbase.h> | 25 #include <objbase.h> |
| 26 | 26 |
| 27 #include "base/win/current_module.h" | 27 #include "base/win/current_module.h" |
| 28 #endif // defined(OS_WIN) | 28 #endif // defined(OS_WIN) |
| 29 | 29 |
| 30 namespace base { | 30 namespace base { |
| 31 namespace internal { | 31 namespace internal { |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 enum WorkerPoolType : size_t { | |
| 36 BACKGROUND_WORKER_POOL = 0, | |
| 37 FOREGROUND_WORKER_POOL, | |
| 38 }; | |
| 39 | |
| 40 static size_t GetThreadPoolIndexForTraits(const TaskTraits& traits) { | |
| 41 return traits.priority() == TaskPriority::BACKGROUND ? BACKGROUND_WORKER_POOL | |
| 42 : FOREGROUND_WORKER_POOL; | |
| 43 } | |
| 44 | |
| 45 std::vector<SchedulerWorkerPoolParams> GetParamsVector() { | |
| 46 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; | |
| 47 | |
| 48 std::vector<SchedulerWorkerPoolParams> params_vector; | |
| 49 | |
| 50 DCHECK_EQ(BACKGROUND_WORKER_POOL, params_vector.size()); | |
| 51 params_vector.emplace_back("Background", ThreadPriority::BACKGROUND, | |
| 52 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()); | |
| 53 | |
| 54 DCHECK_EQ(FOREGROUND_WORKER_POOL, params_vector.size()); | |
| 55 params_vector.emplace_back("Foreground", ThreadPriority::NORMAL, | |
| 56 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()); | |
| 57 | |
| 58 return params_vector; | |
| 59 } | |
| 60 | |
| 61 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test { | 35 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test { |
| 62 public: | 36 public: |
| 63 TaskSchedulerSingleThreadTaskRunnerManagerTest() | 37 TaskSchedulerSingleThreadTaskRunnerManagerTest() |
| 64 : service_thread_("TaskSchedulerServiceThread") {} | 38 : service_thread_("TaskSchedulerServiceThread") {} |
| 65 | 39 |
| 66 void SetUp() override { | 40 void SetUp() override { |
| 67 service_thread_.Start(); | 41 service_thread_.Start(); |
| 68 | |
| 69 delayed_task_manager_ = | 42 delayed_task_manager_ = |
| 70 MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | 43 MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); |
| 71 single_thread_task_runner_manager_ = | 44 single_thread_task_runner_manager_ = |
| 72 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( | 45 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( |
| 73 GetParamsVector(), Bind(&GetThreadPoolIndexForTraits), | |
| 74 &task_tracker_, delayed_task_manager_.get()); | 46 &task_tracker_, delayed_task_manager_.get()); |
| 75 StartSingleThreadTaskRunnerManagerFromSetup(); | 47 StartSingleThreadTaskRunnerManagerFromSetup(); |
| 76 } | 48 } |
| 77 | 49 |
| 78 void TearDown() override { | 50 void TearDown() override { |
| 79 TearDownSingleThreadTaskRunnerManager(); | 51 TearDownSingleThreadTaskRunnerManager(); |
| 80 delayed_task_manager_.reset(); | 52 delayed_task_manager_.reset(); |
| 81 service_thread_.Stop(); | 53 service_thread_.Stop(); |
| 82 } | 54 } |
| 83 | 55 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 void ShouldNotRun() { | 87 void ShouldNotRun() { |
| 116 ADD_FAILURE() << "Ran a task that shouldn't run."; | 88 ADD_FAILURE() << "Ran a task that shouldn't run."; |
| 117 } | 89 } |
| 118 | 90 |
| 119 } // namespace | 91 } // namespace |
| 120 | 92 |
| 121 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 93 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { |
| 122 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 94 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
| 123 single_thread_task_runner_manager_ | 95 single_thread_task_runner_manager_ |
| 124 ->CreateSingleThreadTaskRunnerWithTraits( | 96 ->CreateSingleThreadTaskRunnerWithTraits( |
| 97 "A", ThreadPriority::NORMAL, | |
| 125 TaskTraits().WithShutdownBehavior( | 98 TaskTraits().WithShutdownBehavior( |
| 126 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 99 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 127 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 100 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
| 128 single_thread_task_runner_manager_ | 101 single_thread_task_runner_manager_ |
| 129 ->CreateSingleThreadTaskRunnerWithTraits( | 102 ->CreateSingleThreadTaskRunnerWithTraits( |
| 103 "B", ThreadPriority::NORMAL, | |
| 130 TaskTraits().WithShutdownBehavior( | 104 TaskTraits().WithShutdownBehavior( |
| 131 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 105 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 132 | 106 |
| 133 PlatformThreadRef thread_ref_1; | 107 PlatformThreadRef thread_ref_1; |
| 134 task_runner_1->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_1)); | 108 task_runner_1->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_1)); |
| 135 PlatformThreadRef thread_ref_2; | 109 PlatformThreadRef thread_ref_2; |
| 136 task_runner_2->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_2)); | 110 task_runner_2->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_2)); |
| 137 | 111 |
| 138 task_tracker_.Shutdown(); | 112 task_tracker_.Shutdown(); |
| 139 | 113 |
| 140 ASSERT_FALSE(thread_ref_1.is_null()); | 114 ASSERT_FALSE(thread_ref_1.is_null()); |
| 141 ASSERT_FALSE(thread_ref_2.is_null()); | 115 ASSERT_FALSE(thread_ref_2.is_null()); |
| 142 EXPECT_NE(thread_ref_1, thread_ref_2); | 116 EXPECT_NE(thread_ref_1, thread_ref_2); |
| 143 } | 117 } |
| 144 | 118 |
| 145 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 119 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { |
| 146 // Why are events used here instead of the task tracker? | 120 // Why are events used here instead of the task tracker? |
| 147 // Shutting down can cause priorities to get raised. This means we have to use | 121 // Shutting down can cause priorities to get raised. This means we have to use |
| 148 // events to determine when a task is run. | 122 // events to determine when a task is run. |
| 149 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 123 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
| 150 single_thread_task_runner_manager_ | 124 single_thread_task_runner_manager_ |
| 151 ->CreateSingleThreadTaskRunnerWithTraits( | 125 ->CreateSingleThreadTaskRunnerWithTraits( |
| 126 "Background", ThreadPriority::BACKGROUND, | |
| 152 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 127 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); |
| 153 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = | 128 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = |
| 154 single_thread_task_runner_manager_ | 129 single_thread_task_runner_manager_ |
| 155 ->CreateSingleThreadTaskRunnerWithTraits( | 130 ->CreateSingleThreadTaskRunnerWithTraits( |
| 131 "Normal", ThreadPriority::NORMAL, | |
| 156 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | 132 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); |
| 157 scoped_refptr<SingleThreadTaskRunner> task_runner_user_blocking = | |
| 158 single_thread_task_runner_manager_ | |
| 159 ->CreateSingleThreadTaskRunnerWithTraits( | |
| 160 TaskTraits() | |
| 161 .WithPriority(TaskPriority::USER_BLOCKING) | |
| 162 .WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
| 163 | 133 |
| 164 ThreadPriority thread_priority_background; | 134 ThreadPriority thread_priority_background; |
| 165 task_runner_background->PostTask( | 135 task_runner_background->PostTask( |
| 166 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_background)); | 136 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_background)); |
| 167 WaitableEvent waitable_event_background( | 137 WaitableEvent waitable_event_background( |
| 168 WaitableEvent::ResetPolicy::MANUAL, | 138 WaitableEvent::ResetPolicy::MANUAL, |
| 169 WaitableEvent::InitialState::NOT_SIGNALED); | 139 WaitableEvent::InitialState::NOT_SIGNALED); |
| 170 task_runner_background->PostTask( | 140 task_runner_background->PostTask( |
| 171 FROM_HERE, | 141 FROM_HERE, |
| 172 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 142 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_background))); |
| 173 | 143 |
| 174 ThreadPriority thread_priority_user_visible; | 144 ThreadPriority thread_priority_normal; |
| 175 task_runner_user_visible->PostTask( | 145 task_runner_normal->PostTask( |
| 176 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_user_visible)); | 146 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_normal)); |
| 177 WaitableEvent waitable_event_user_visible( | 147 WaitableEvent waitable_event_normal( |
| 178 WaitableEvent::ResetPolicy::MANUAL, | 148 WaitableEvent::ResetPolicy::MANUAL, |
| 179 WaitableEvent::InitialState::NOT_SIGNALED); | 149 WaitableEvent::InitialState::NOT_SIGNALED); |
| 180 task_runner_user_visible->PostTask( | 150 task_runner_normal->PostTask( |
| 181 FROM_HERE, | 151 FROM_HERE, |
| 182 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_user_visible))); | 152 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_normal))); |
| 183 | |
| 184 ThreadPriority thread_priority_user_blocking; | |
| 185 task_runner_user_blocking->PostTask( | |
| 186 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_user_blocking)); | |
|
robliao
2017/04/12 19:08:13
What's the rationale for removing this test?
fdoray
2017/04/12 20:00:23
Since SchedulerSingleThreadTaskRunnerManager doesn
| |
| 187 WaitableEvent waitable_event_user_blocking( | |
| 188 WaitableEvent::ResetPolicy::MANUAL, | |
| 189 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 190 task_runner_user_blocking->PostTask( | |
| 191 FROM_HERE, | |
| 192 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_user_blocking))); | |
| 193 | 153 |
| 194 waitable_event_background.Wait(); | 154 waitable_event_background.Wait(); |
| 195 waitable_event_user_visible.Wait(); | 155 waitable_event_normal.Wait(); |
| 196 waitable_event_user_blocking.Wait(); | |
| 197 | 156 |
| 198 if (Lock::HandlesMultipleThreadPriorities()) | 157 if (Lock::HandlesMultipleThreadPriorities()) |
| 199 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 158 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); |
| 200 else | 159 else |
| 201 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 160 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); |
| 202 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); | 161 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); |
| 203 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); | |
| 204 } | 162 } |
| 205 | 163 |
| 206 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 164 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { |
| 207 auto task_runner = single_thread_task_runner_manager_ | 165 auto task_runner = single_thread_task_runner_manager_ |
| 208 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 166 ->CreateSingleThreadTaskRunnerWithTraits( |
| 167 "A", ThreadPriority::NORMAL, TaskTraits()); | |
| 209 task_tracker_.Shutdown(); | 168 task_tracker_.Shutdown(); |
| 210 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRun))); | 169 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRun))); |
| 211 } | 170 } |
| 212 | 171 |
| 213 // Verify that a Task runs shortly after its delay expires. | 172 // Verify that a Task runs shortly after its delay expires. |
| 214 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 173 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { |
| 215 TimeTicks start_time = TimeTicks::Now(); | 174 TimeTicks start_time = TimeTicks::Now(); |
| 216 | 175 |
| 217 // Post a task with a short delay. | 176 // Post a task with a short delay. |
| 218 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 177 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
| 219 WaitableEvent::InitialState::NOT_SIGNALED); | 178 WaitableEvent::InitialState::NOT_SIGNALED); |
| 220 auto task_runner = single_thread_task_runner_manager_ | 179 auto task_runner = single_thread_task_runner_manager_ |
| 221 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 180 ->CreateSingleThreadTaskRunnerWithTraits( |
| 181 "B", ThreadPriority::NORMAL, TaskTraits()); | |
| 222 EXPECT_TRUE(task_runner->PostDelayedTask( | 182 EXPECT_TRUE(task_runner->PostDelayedTask( |
| 223 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_ran)), | 183 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_ran)), |
| 224 TestTimeouts::tiny_timeout())); | 184 TestTimeouts::tiny_timeout())); |
| 225 | 185 |
| 226 // Wait until the task runs. | 186 // Wait until the task runs. |
| 227 task_ran.Wait(); | 187 task_ran.Wait(); |
| 228 | 188 |
| 229 // Expect the task to run after its delay expires, but not more than 250 ms | 189 // Expect the task to run after its delay expires, but not more than 250 ms |
| 230 // after that. | 190 // after that. |
| 231 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 191 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
| 232 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 192 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
| 233 EXPECT_LT(actual_delay, | 193 EXPECT_LT(actual_delay, |
| 234 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 194 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
| 235 } | 195 } |
| 236 | 196 |
| 237 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 197 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, |
| 238 RunsTasksOnCurrentThread) { | 198 RunsTasksOnCurrentThread) { |
| 239 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 199 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
| 240 single_thread_task_runner_manager_ | 200 single_thread_task_runner_manager_ |
| 241 ->CreateSingleThreadTaskRunnerWithTraits( | 201 ->CreateSingleThreadTaskRunnerWithTraits( |
| 202 "A", ThreadPriority::NORMAL, | |
| 242 TaskTraits().WithShutdownBehavior( | 203 TaskTraits().WithShutdownBehavior( |
| 243 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 204 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 244 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 205 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
| 245 single_thread_task_runner_manager_ | 206 single_thread_task_runner_manager_ |
| 246 ->CreateSingleThreadTaskRunnerWithTraits( | 207 ->CreateSingleThreadTaskRunnerWithTraits( |
| 208 "B", ThreadPriority::NORMAL, | |
| 247 TaskTraits().WithShutdownBehavior( | 209 TaskTraits().WithShutdownBehavior( |
| 248 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 210 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 249 | 211 |
| 250 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 212 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); |
| 251 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 213 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
| 252 | 214 |
| 253 task_runner_1->PostTask( | 215 task_runner_1->PostTask( |
| 254 FROM_HERE, Bind( | 216 FROM_HERE, Bind( |
| 255 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 217 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, |
| 256 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 218 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 // Exercises the codepath where the workers are unavailable for unregistration | 282 // Exercises the codepath where the workers are unavailable for unregistration |
| 321 // because of a Join call. | 283 // because of a Join call. |
| 322 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 284 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 323 WaitableEvent::InitialState::NOT_SIGNALED); | 285 WaitableEvent::InitialState::NOT_SIGNALED); |
| 324 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 286 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
| 325 WaitableEvent::InitialState::NOT_SIGNALED); | 287 WaitableEvent::InitialState::NOT_SIGNALED); |
| 326 | 288 |
| 327 { | 289 { |
| 328 auto task_runner = single_thread_task_runner_manager_ | 290 auto task_runner = single_thread_task_runner_manager_ |
| 329 ->CreateSingleThreadTaskRunnerWithTraits( | 291 ->CreateSingleThreadTaskRunnerWithTraits( |
| 292 "A", ThreadPriority::NORMAL, | |
| 330 TaskTraits().WithBaseSyncPrimitives()); | 293 TaskTraits().WithBaseSyncPrimitives()); |
| 331 EXPECT_TRUE(task_runner->PostTask( | 294 EXPECT_TRUE(task_runner->PostTask( |
| 332 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 295 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); |
| 333 EXPECT_TRUE(task_runner->PostTask( | 296 EXPECT_TRUE(task_runner->PostTask( |
| 334 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 297 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
| 335 } | 298 } |
| 336 | 299 |
| 337 task_running.Wait(); | 300 task_running.Wait(); |
| 338 CallJoinFromDifferentThread join_from_different_thread( | 301 CallJoinFromDifferentThread join_from_different_thread( |
| 339 single_thread_task_runner_manager_.get()); | 302 single_thread_task_runner_manager_.get()); |
| 340 join_from_different_thread.Start(); | 303 join_from_different_thread.Start(); |
| 341 join_from_different_thread.WaitForRunToStart(); | 304 join_from_different_thread.WaitForRunToStart(); |
| 342 task_blocking.Signal(); | 305 task_blocking.Signal(); |
| 343 join_from_different_thread.Join(); | 306 join_from_different_thread.Join(); |
| 344 } | 307 } |
| 345 | 308 |
| 346 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 309 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
| 347 ConcurrentJoinExtraSkippedTask) { | 310 ConcurrentJoinExtraSkippedTask) { |
| 348 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 311 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
| 349 // SingleThreadTaskRunners to unregister themselves. | 312 // SingleThreadTaskRunners to unregister themselves. |
| 350 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 313 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 351 WaitableEvent::InitialState::NOT_SIGNALED); | 314 WaitableEvent::InitialState::NOT_SIGNALED); |
| 352 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 315 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
| 353 WaitableEvent::InitialState::NOT_SIGNALED); | 316 WaitableEvent::InitialState::NOT_SIGNALED); |
| 354 | 317 |
| 355 { | 318 { |
| 356 auto task_runner = single_thread_task_runner_manager_ | 319 auto task_runner = single_thread_task_runner_manager_ |
| 357 ->CreateSingleThreadTaskRunnerWithTraits( | 320 ->CreateSingleThreadTaskRunnerWithTraits( |
| 321 "A", ThreadPriority::NORMAL, | |
| 358 TaskTraits().WithBaseSyncPrimitives()); | 322 TaskTraits().WithBaseSyncPrimitives()); |
| 359 EXPECT_TRUE(task_runner->PostTask( | 323 EXPECT_TRUE(task_runner->PostTask( |
| 360 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 324 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); |
| 361 EXPECT_TRUE(task_runner->PostTask( | 325 EXPECT_TRUE(task_runner->PostTask( |
| 362 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 326 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
| 363 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, Bind(&DoNothing))); | 327 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, Bind(&DoNothing))); |
| 364 } | 328 } |
| 365 | 329 |
| 366 task_running.Wait(); | 330 task_running.Wait(); |
| 367 CallJoinFromDifferentThread join_from_different_thread( | 331 CallJoinFromDifferentThread join_from_different_thread( |
| 368 single_thread_task_runner_manager_.get()); | 332 single_thread_task_runner_manager_.get()); |
| 369 join_from_different_thread.Start(); | 333 join_from_different_thread.Start(); |
| 370 join_from_different_thread.WaitForRunToStart(); | 334 join_from_different_thread.WaitForRunToStart(); |
| 371 task_blocking.Signal(); | 335 task_blocking.Signal(); |
| 372 join_from_different_thread.Join(); | 336 join_from_different_thread.Join(); |
| 373 } | 337 } |
| 374 | 338 |
| 375 #if defined(OS_WIN) | 339 #if defined(OS_WIN) |
| 376 | 340 |
| 377 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 341 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { |
| 378 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 342 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
| 379 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 343 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 344 "A", ThreadPriority::NORMAL, | |
| 380 TaskTraits().WithShutdownBehavior( | 345 TaskTraits().WithShutdownBehavior( |
| 381 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 346 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 382 | 347 |
| 383 com_task_runner->PostTask( | 348 com_task_runner->PostTask( |
| 384 FROM_HERE, Bind([]() { | 349 FROM_HERE, Bind([]() { |
| 385 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 350 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
| 386 if (SUCCEEDED(hr)) { | 351 if (SUCCEEDED(hr)) { |
| 387 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 352 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
| 388 CoUninitialize(); | 353 CoUninitialize(); |
| 389 } | 354 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 bool register_class_succeeded_ = false; | 398 bool register_class_succeeded_ = false; |
| 434 | 399 |
| 435 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 400 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); |
| 436 }; | 401 }; |
| 437 | 402 |
| 438 } // namespace | 403 } // namespace |
| 439 | 404 |
| 440 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 405 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { |
| 441 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 406 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
| 442 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 407 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 408 "A", ThreadPriority::NORMAL, | |
| 443 TaskTraits().WithShutdownBehavior( | 409 TaskTraits().WithShutdownBehavior( |
| 444 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 410 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 445 HWND hwnd = nullptr; | 411 HWND hwnd = nullptr; |
| 446 // HWNDs process messages on the thread that created them, so we have to | 412 // HWNDs process messages on the thread that created them, so we have to |
| 447 // create them within the context of the task runner to properly simulate a | 413 // create them within the context of the task runner to properly simulate a |
| 448 // COM callback. | 414 // COM callback. |
| 449 com_task_runner->PostTask( | 415 com_task_runner->PostTask( |
| 450 FROM_HERE, | 416 FROM_HERE, |
| 451 Bind([](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 417 Bind([](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, |
| 452 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 418 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 485 } // namespace | 451 } // namespace |
| 486 | 452 |
| 487 // Verify that a task posted before Start() doesn't run until Start() is called. | 453 // Verify that a task posted before Start() doesn't run until Start() is called. |
| 488 // Don't use the TaskSchedulerSingleThreadTaskRunnerManagerTest fixture | 454 // Don't use the TaskSchedulerSingleThreadTaskRunnerManagerTest fixture |
| 489 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, | 455 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, |
| 490 PostTaskBeforeStart) { | 456 PostTaskBeforeStart) { |
| 491 AtomicFlag manager_started; | 457 AtomicFlag manager_started; |
| 492 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 458 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 493 WaitableEvent::InitialState::NOT_SIGNALED); | 459 WaitableEvent::InitialState::NOT_SIGNALED); |
| 494 single_thread_task_runner_manager_ | 460 single_thread_task_runner_manager_ |
| 495 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()) | 461 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, |
| 462 TaskTraits()) | |
| 496 ->PostTask( | 463 ->PostTask( |
| 497 FROM_HERE, | 464 FROM_HERE, |
| 498 Bind( | 465 Bind( |
| 499 [](WaitableEvent* task_running, AtomicFlag* manager_started) { | 466 [](WaitableEvent* task_running, AtomicFlag* manager_started) { |
| 500 task_running->Signal(); | 467 task_running->Signal(); |
| 501 | 468 |
| 502 // The task should not run before Start(). | 469 // The task should not run before Start(). |
| 503 EXPECT_TRUE(manager_started->IsSet()); | 470 EXPECT_TRUE(manager_started->IsSet()); |
| 504 }, | 471 }, |
| 505 Unretained(&task_running), Unretained(&manager_started))); | 472 Unretained(&task_running), Unretained(&manager_started))); |
| 506 | 473 |
| 507 // Wait a little bit to make sure that the task isn't scheduled before start. | 474 // Wait a little bit to make sure that the task isn't scheduled before start. |
| 508 // Note: This test won't catch a case where the task is scheduled between | 475 // Note: This test won't catch a case where the task is scheduled between |
| 509 // setting |manager_started| and calling Start(). However, we expect the test | 476 // setting |manager_started| and calling Start(). However, we expect the test |
| 510 // to be flaky if the tested code allows that to happen. | 477 // to be flaky if the tested code allows that to happen. |
| 511 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 478 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 512 manager_started.Set(); | 479 manager_started.Set(); |
| 513 single_thread_task_runner_manager_->Start(); | 480 single_thread_task_runner_manager_->Start(); |
| 514 | 481 |
| 515 // This should not hang if the task is scheduled after Start(). | 482 // This should not hang if the task is scheduled after Start(). |
| 516 task_running.Wait(); | 483 task_running.Wait(); |
| 517 } | 484 } |
| 518 | 485 |
| 519 } // namespace internal | 486 } // namespace internal |
| 520 } // namespace base | 487 } // namespace base |
| OLD | NEW |