| 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/lock.h" | 9 #include "base/synchronization/lock.h" |
| 10 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 ->CreateSingleThreadTaskRunnerWithTraits( | 117 ->CreateSingleThreadTaskRunnerWithTraits( |
| 118 TaskTraits().WithShutdownBehavior( | 118 TaskTraits().WithShutdownBehavior( |
| 119 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 119 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 120 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 120 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
| 121 single_thread_task_runner_manager_ | 121 single_thread_task_runner_manager_ |
| 122 ->CreateSingleThreadTaskRunnerWithTraits( | 122 ->CreateSingleThreadTaskRunnerWithTraits( |
| 123 TaskTraits().WithShutdownBehavior( | 123 TaskTraits().WithShutdownBehavior( |
| 124 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 124 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 125 | 125 |
| 126 PlatformThreadRef thread_ref_1; | 126 PlatformThreadRef thread_ref_1; |
| 127 task_runner_1->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_1)); | 127 task_runner_1->PostTask(FROM_HERE, |
| 128 BindOnce(&CaptureThreadRef, &thread_ref_1)); |
| 128 PlatformThreadRef thread_ref_2; | 129 PlatformThreadRef thread_ref_2; |
| 129 task_runner_2->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_2)); | 130 task_runner_2->PostTask(FROM_HERE, |
| 131 BindOnce(&CaptureThreadRef, &thread_ref_2)); |
| 130 | 132 |
| 131 task_tracker_.Shutdown(); | 133 task_tracker_.Shutdown(); |
| 132 | 134 |
| 133 ASSERT_FALSE(thread_ref_1.is_null()); | 135 ASSERT_FALSE(thread_ref_1.is_null()); |
| 134 ASSERT_FALSE(thread_ref_2.is_null()); | 136 ASSERT_FALSE(thread_ref_2.is_null()); |
| 135 EXPECT_NE(thread_ref_1, thread_ref_2); | 137 EXPECT_NE(thread_ref_1, thread_ref_2); |
| 136 } | 138 } |
| 137 | 139 |
| 138 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 140 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { |
| 139 // Why are events used here instead of the task tracker? | 141 // Why are events used here instead of the task tracker? |
| 140 // Shutting down can cause priorities to get raised. This means we have to use | 142 // Shutting down can cause priorities to get raised. This means we have to use |
| 141 // events to determine when a task is run. | 143 // events to determine when a task is run. |
| 142 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 144 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
| 143 single_thread_task_runner_manager_ | 145 single_thread_task_runner_manager_ |
| 144 ->CreateSingleThreadTaskRunnerWithTraits( | 146 ->CreateSingleThreadTaskRunnerWithTraits( |
| 145 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 147 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); |
| 146 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = | 148 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = |
| 147 single_thread_task_runner_manager_ | 149 single_thread_task_runner_manager_ |
| 148 ->CreateSingleThreadTaskRunnerWithTraits( | 150 ->CreateSingleThreadTaskRunnerWithTraits( |
| 149 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | 151 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); |
| 150 scoped_refptr<SingleThreadTaskRunner> task_runner_user_blocking = | 152 scoped_refptr<SingleThreadTaskRunner> task_runner_user_blocking = |
| 151 single_thread_task_runner_manager_ | 153 single_thread_task_runner_manager_ |
| 152 ->CreateSingleThreadTaskRunnerWithTraits( | 154 ->CreateSingleThreadTaskRunnerWithTraits( |
| 153 TaskTraits() | 155 TaskTraits() |
| 154 .WithPriority(TaskPriority::USER_BLOCKING) | 156 .WithPriority(TaskPriority::USER_BLOCKING) |
| 155 .WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 157 .WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 156 | 158 |
| 157 ThreadPriority thread_priority_background; | 159 ThreadPriority thread_priority_background; |
| 158 task_runner_background->PostTask( | 160 task_runner_background->PostTask( |
| 159 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_background)); | 161 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); |
| 160 WaitableEvent waitable_event_background( | 162 WaitableEvent waitable_event_background( |
| 161 WaitableEvent::ResetPolicy::MANUAL, | 163 WaitableEvent::ResetPolicy::MANUAL, |
| 162 WaitableEvent::InitialState::NOT_SIGNALED); | 164 WaitableEvent::InitialState::NOT_SIGNALED); |
| 163 task_runner_background->PostTask( | 165 task_runner_background->PostTask( |
| 164 FROM_HERE, | 166 FROM_HERE, |
| 165 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 167 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); |
| 166 | 168 |
| 167 ThreadPriority thread_priority_user_visible; | 169 ThreadPriority thread_priority_user_visible; |
| 168 task_runner_user_visible->PostTask( | 170 task_runner_user_visible->PostTask( |
| 169 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_user_visible)); | 171 FROM_HERE, |
| 172 BindOnce(&CaptureThreadPriority, &thread_priority_user_visible)); |
| 170 WaitableEvent waitable_event_user_visible( | 173 WaitableEvent waitable_event_user_visible( |
| 171 WaitableEvent::ResetPolicy::MANUAL, | 174 WaitableEvent::ResetPolicy::MANUAL, |
| 172 WaitableEvent::InitialState::NOT_SIGNALED); | 175 WaitableEvent::InitialState::NOT_SIGNALED); |
| 173 task_runner_user_visible->PostTask( | 176 task_runner_user_visible->PostTask( |
| 174 FROM_HERE, | 177 FROM_HERE, BindOnce(&WaitableEvent::Signal, |
| 175 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_user_visible))); | 178 Unretained(&waitable_event_user_visible))); |
| 176 | 179 |
| 177 ThreadPriority thread_priority_user_blocking; | 180 ThreadPriority thread_priority_user_blocking; |
| 178 task_runner_user_blocking->PostTask( | 181 task_runner_user_blocking->PostTask( |
| 179 FROM_HERE, Bind(&CaptureThreadPriority, &thread_priority_user_blocking)); | 182 FROM_HERE, |
| 183 BindOnce(&CaptureThreadPriority, &thread_priority_user_blocking)); |
| 180 WaitableEvent waitable_event_user_blocking( | 184 WaitableEvent waitable_event_user_blocking( |
| 181 WaitableEvent::ResetPolicy::MANUAL, | 185 WaitableEvent::ResetPolicy::MANUAL, |
| 182 WaitableEvent::InitialState::NOT_SIGNALED); | 186 WaitableEvent::InitialState::NOT_SIGNALED); |
| 183 task_runner_user_blocking->PostTask( | 187 task_runner_user_blocking->PostTask( |
| 184 FROM_HERE, | 188 FROM_HERE, BindOnce(&WaitableEvent::Signal, |
| 185 Bind(&WaitableEvent::Signal, Unretained(&waitable_event_user_blocking))); | 189 Unretained(&waitable_event_user_blocking))); |
| 186 | 190 |
| 187 waitable_event_background.Wait(); | 191 waitable_event_background.Wait(); |
| 188 waitable_event_user_visible.Wait(); | 192 waitable_event_user_visible.Wait(); |
| 189 waitable_event_user_blocking.Wait(); | 193 waitable_event_user_blocking.Wait(); |
| 190 | 194 |
| 191 if (Lock::HandlesMultipleThreadPriorities()) | 195 if (Lock::HandlesMultipleThreadPriorities()) |
| 192 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 196 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); |
| 193 else | 197 else |
| 194 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 198 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); |
| 195 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); | 199 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); |
| 196 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); | 200 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); |
| 197 } | 201 } |
| 198 | 202 |
| 199 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 203 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { |
| 200 auto task_runner = single_thread_task_runner_manager_ | 204 auto task_runner = single_thread_task_runner_manager_ |
| 201 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 205 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
| 202 task_tracker_.Shutdown(); | 206 task_tracker_.Shutdown(); |
| 203 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRun))); | 207 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); |
| 204 } | 208 } |
| 205 | 209 |
| 206 // Verify that a Task runs shortly after its delay expires. | 210 // Verify that a Task runs shortly after its delay expires. |
| 207 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 211 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { |
| 208 TimeTicks start_time = TimeTicks::Now(); | 212 TimeTicks start_time = TimeTicks::Now(); |
| 209 | 213 |
| 210 // Post a task with a short delay. | 214 // Post a task with a short delay. |
| 211 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 215 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
| 212 WaitableEvent::InitialState::NOT_SIGNALED); | 216 WaitableEvent::InitialState::NOT_SIGNALED); |
| 213 auto task_runner = single_thread_task_runner_manager_ | 217 auto task_runner = single_thread_task_runner_manager_ |
| 214 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 218 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
| 215 EXPECT_TRUE(task_runner->PostDelayedTask( | 219 EXPECT_TRUE(task_runner->PostDelayedTask( |
| 216 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_ran)), | 220 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), |
| 217 TestTimeouts::tiny_timeout())); | 221 TestTimeouts::tiny_timeout())); |
| 218 | 222 |
| 219 // Wait until the task runs. | 223 // Wait until the task runs. |
| 220 task_ran.Wait(); | 224 task_ran.Wait(); |
| 221 | 225 |
| 222 // Expect the task to run after its delay expires, but not more than 250 ms | 226 // Expect the task to run after its delay expires, but not more than 250 ms |
| 223 // after that. | 227 // after that. |
| 224 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 228 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
| 225 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 229 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
| 226 EXPECT_LT(actual_delay, | 230 EXPECT_LT(actual_delay, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 237 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 241 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
| 238 single_thread_task_runner_manager_ | 242 single_thread_task_runner_manager_ |
| 239 ->CreateSingleThreadTaskRunnerWithTraits( | 243 ->CreateSingleThreadTaskRunnerWithTraits( |
| 240 TaskTraits().WithShutdownBehavior( | 244 TaskTraits().WithShutdownBehavior( |
| 241 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 245 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 242 | 246 |
| 243 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 247 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); |
| 244 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 248 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
| 245 | 249 |
| 246 task_runner_1->PostTask( | 250 task_runner_1->PostTask( |
| 247 FROM_HERE, Bind( | 251 FROM_HERE, BindOnce( |
| 248 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 252 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, |
| 249 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 253 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { |
| 250 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); | 254 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); |
| 251 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 255 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
| 252 }, | 256 }, |
| 253 task_runner_1, task_runner_2)); | 257 task_runner_1, task_runner_2)); |
| 254 | 258 |
| 255 task_runner_2->PostTask( | 259 task_runner_2->PostTask( |
| 256 FROM_HERE, Bind( | 260 FROM_HERE, BindOnce( |
| 257 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 261 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, |
| 258 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 262 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { |
| 259 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 263 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); |
| 260 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread()); | 264 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread()); |
| 261 }, | 265 }, |
| 262 task_runner_1, task_runner_2)); | 266 task_runner_1, task_runner_2)); |
| 263 | 267 |
| 264 task_tracker_.Shutdown(); | 268 task_tracker_.Shutdown(); |
| 265 } | 269 } |
| 266 | 270 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 319 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 316 WaitableEvent::InitialState::NOT_SIGNALED); | 320 WaitableEvent::InitialState::NOT_SIGNALED); |
| 317 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 321 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
| 318 WaitableEvent::InitialState::NOT_SIGNALED); | 322 WaitableEvent::InitialState::NOT_SIGNALED); |
| 319 | 323 |
| 320 { | 324 { |
| 321 auto task_runner = single_thread_task_runner_manager_ | 325 auto task_runner = single_thread_task_runner_manager_ |
| 322 ->CreateSingleThreadTaskRunnerWithTraits( | 326 ->CreateSingleThreadTaskRunnerWithTraits( |
| 323 TaskTraits().WithBaseSyncPrimitives()); | 327 TaskTraits().WithBaseSyncPrimitives()); |
| 324 EXPECT_TRUE(task_runner->PostTask( | 328 EXPECT_TRUE(task_runner->PostTask( |
| 325 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 329 FROM_HERE, |
| 330 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
| 326 EXPECT_TRUE(task_runner->PostTask( | 331 EXPECT_TRUE(task_runner->PostTask( |
| 327 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 332 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
| 328 } | 333 } |
| 329 | 334 |
| 330 task_running.Wait(); | 335 task_running.Wait(); |
| 331 CallJoinFromDifferentThread join_from_different_thread( | 336 CallJoinFromDifferentThread join_from_different_thread( |
| 332 single_thread_task_runner_manager_.get()); | 337 single_thread_task_runner_manager_.get()); |
| 333 join_from_different_thread.Start(); | 338 join_from_different_thread.Start(); |
| 334 join_from_different_thread.WaitForRunToStart(); | 339 join_from_different_thread.WaitForRunToStart(); |
| 335 task_blocking.Signal(); | 340 task_blocking.Signal(); |
| 336 join_from_different_thread.Join(); | 341 join_from_different_thread.Join(); |
| 337 } | 342 } |
| 338 | 343 |
| 339 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 344 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
| 340 ConcurrentJoinExtraSkippedTask) { | 345 ConcurrentJoinExtraSkippedTask) { |
| 341 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 346 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
| 342 // SingleThreadTaskRunners to unregister themselves. | 347 // SingleThreadTaskRunners to unregister themselves. |
| 343 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 348 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 344 WaitableEvent::InitialState::NOT_SIGNALED); | 349 WaitableEvent::InitialState::NOT_SIGNALED); |
| 345 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 350 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
| 346 WaitableEvent::InitialState::NOT_SIGNALED); | 351 WaitableEvent::InitialState::NOT_SIGNALED); |
| 347 | 352 |
| 348 { | 353 { |
| 349 auto task_runner = single_thread_task_runner_manager_ | 354 auto task_runner = single_thread_task_runner_manager_ |
| 350 ->CreateSingleThreadTaskRunnerWithTraits( | 355 ->CreateSingleThreadTaskRunnerWithTraits( |
| 351 TaskTraits().WithBaseSyncPrimitives()); | 356 TaskTraits().WithBaseSyncPrimitives()); |
| 352 EXPECT_TRUE(task_runner->PostTask( | 357 EXPECT_TRUE(task_runner->PostTask( |
| 353 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 358 FROM_HERE, |
| 359 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
| 354 EXPECT_TRUE(task_runner->PostTask( | 360 EXPECT_TRUE(task_runner->PostTask( |
| 355 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 361 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
| 356 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, Bind(&DoNothing))); | 362 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); |
| 357 } | 363 } |
| 358 | 364 |
| 359 task_running.Wait(); | 365 task_running.Wait(); |
| 360 CallJoinFromDifferentThread join_from_different_thread( | 366 CallJoinFromDifferentThread join_from_different_thread( |
| 361 single_thread_task_runner_manager_.get()); | 367 single_thread_task_runner_manager_.get()); |
| 362 join_from_different_thread.Start(); | 368 join_from_different_thread.Start(); |
| 363 join_from_different_thread.WaitForRunToStart(); | 369 join_from_different_thread.WaitForRunToStart(); |
| 364 task_blocking.Signal(); | 370 task_blocking.Signal(); |
| 365 join_from_different_thread.Join(); | 371 join_from_different_thread.Join(); |
| 366 } | 372 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 com_task_runner->PostTask( | 461 com_task_runner->PostTask( |
| 456 FROM_HERE, Bind([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); | 462 FROM_HERE, Bind([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); |
| 457 | 463 |
| 458 task_tracker_.Shutdown(); | 464 task_tracker_.Shutdown(); |
| 459 } | 465 } |
| 460 | 466 |
| 461 #endif // defined(OS_WIN) | 467 #endif // defined(OS_WIN) |
| 462 | 468 |
| 463 } // namespace internal | 469 } // namespace internal |
| 464 } // namespace base | 470 } // namespace base |
| OLD | NEW |