| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/task_tracker.h" | 5 #include "base/task_scheduler/task_tracker.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/callback.h" | 14 #include "base/callback.h" |
| 14 #include "base/logging.h" | 15 #include "base/logging.h" |
| 15 #include "base/macros.h" | 16 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
| 17 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
| 18 #include "base/sequence_token.h" | 19 #include "base/sequence_token.h" |
| 19 #include "base/sequenced_task_runner.h" | 20 #include "base/sequenced_task_runner.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 }; | 71 }; |
| 71 | 72 |
| 72 ThreadPostingAndRunningTask(TaskTracker* tracker, | 73 ThreadPostingAndRunningTask(TaskTracker* tracker, |
| 73 Task* task, | 74 Task* task, |
| 74 Action action, | 75 Action action, |
| 75 bool expect_post_succeeds) | 76 bool expect_post_succeeds) |
| 76 : SimpleThread("ThreadPostingAndRunningTask"), | 77 : SimpleThread("ThreadPostingAndRunningTask"), |
| 77 tracker_(tracker), | 78 tracker_(tracker), |
| 78 task_(task), | 79 task_(task), |
| 79 action_(action), | 80 action_(action), |
| 80 expect_post_succeeds_(expect_post_succeeds) {} | 81 expect_post_succeeds_(expect_post_succeeds) { |
| 82 EXPECT_TRUE(task_); |
| 83 |
| 84 // Ownership of the Task is required to run it. |
| 85 EXPECT_NE(Action::RUN, action_); |
| 86 EXPECT_NE(Action::WILL_POST_AND_RUN, action_); |
| 87 } |
| 88 |
| 89 ThreadPostingAndRunningTask(TaskTracker* tracker, |
| 90 std::unique_ptr<Task> task, |
| 91 Action action, |
| 92 bool expect_post_succeeds) |
| 93 : SimpleThread("ThreadPostingAndRunningTask"), |
| 94 tracker_(tracker), |
| 95 task_(task.get()), |
| 96 owned_task_(std::move(task)), |
| 97 action_(action), |
| 98 expect_post_succeeds_(expect_post_succeeds) { |
| 99 EXPECT_TRUE(task_); |
| 100 } |
| 81 | 101 |
| 82 private: | 102 private: |
| 83 void Run() override { | 103 void Run() override { |
| 84 bool post_succeeded = true; | 104 bool post_succeeded = true; |
| 85 if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) { | 105 if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) { |
| 86 post_succeeded = tracker_->WillPostTask(task_); | 106 post_succeeded = tracker_->WillPostTask(task_); |
| 87 EXPECT_EQ(expect_post_succeeds_, post_succeeded); | 107 EXPECT_EQ(expect_post_succeeds_, post_succeeded); |
| 88 } | 108 } |
| 89 if (post_succeeded && | 109 if (post_succeeded && |
| 90 (action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) { | 110 (action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) { |
| 91 tracker_->RunTask(task_, SequenceToken::Create()); | 111 EXPECT_TRUE(owned_task_); |
| 112 tracker_->RunTask(std::move(owned_task_), SequenceToken::Create()); |
| 92 } | 113 } |
| 93 } | 114 } |
| 94 | 115 |
| 95 TaskTracker* const tracker_; | 116 TaskTracker* const tracker_; |
| 96 Task* const task_; | 117 Task* const task_; |
| 118 std::unique_ptr<Task> owned_task_; |
| 97 const Action action_; | 119 const Action action_; |
| 98 const bool expect_post_succeeds_; | 120 const bool expect_post_succeeds_; |
| 99 | 121 |
| 100 DISALLOW_COPY_AND_ASSIGN(ThreadPostingAndRunningTask); | 122 DISALLOW_COPY_AND_ASSIGN(ThreadPostingAndRunningTask); |
| 101 }; | 123 }; |
| 102 | 124 |
| 103 class ScopedSetSingletonAllowed { | 125 class ScopedSetSingletonAllowed { |
| 104 public: | 126 public: |
| 105 ScopedSetSingletonAllowed(bool singleton_allowed) | 127 ScopedSetSingletonAllowed(bool singleton_allowed) |
| 106 : previous_value_( | 128 : previous_value_( |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 } // namespace | 244 } // namespace |
| 223 | 245 |
| 224 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) { | 246 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) { |
| 225 std::unique_ptr<Task> task(CreateTask(GetParam())); | 247 std::unique_ptr<Task> task(CreateTask(GetParam())); |
| 226 | 248 |
| 227 // Inform |task_tracker_| that |task| will be posted. | 249 // Inform |task_tracker_| that |task| will be posted. |
| 228 EXPECT_TRUE(tracker_.WillPostTask(task.get())); | 250 EXPECT_TRUE(tracker_.WillPostTask(task.get())); |
| 229 | 251 |
| 230 // Run the task. | 252 // Run the task. |
| 231 EXPECT_EQ(0U, NumTasksExecuted()); | 253 EXPECT_EQ(0U, NumTasksExecuted()); |
| 232 EXPECT_TRUE(tracker_.RunTask(task.get(), SequenceToken::Create())); | 254 EXPECT_TRUE(tracker_.RunTask(std::move(task), SequenceToken::Create())); |
| 233 EXPECT_EQ(1U, NumTasksExecuted()); | 255 EXPECT_EQ(1U, NumTasksExecuted()); |
| 234 | 256 |
| 235 // Shutdown() shouldn't block. | 257 // Shutdown() shouldn't block. |
| 236 tracker_.Shutdown(); | 258 tracker_.Shutdown(); |
| 237 } | 259 } |
| 238 | 260 |
| 239 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { | 261 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { |
| 240 // Create a task that will block until |event| is signaled. | 262 // Create a task that will block until |event| is signaled. |
| 241 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC, | 263 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC, |
| 242 WaitableEvent::InitialState::NOT_SIGNALED); | 264 WaitableEvent::InitialState::NOT_SIGNALED); |
| 243 Task blocked_task(FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), | 265 auto blocked_task = base::MakeUnique<Task>( |
| 244 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | 266 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), |
| 267 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 245 | 268 |
| 246 // Inform |task_tracker_| that |blocked_task| will be posted. | 269 // Inform |task_tracker_| that |blocked_task| will be posted. |
| 247 EXPECT_TRUE(tracker_.WillPostTask(&blocked_task)); | 270 EXPECT_TRUE(tracker_.WillPostTask(blocked_task.get())); |
| 248 | 271 |
| 249 // Run the task asynchronouly. | 272 // Run the task asynchronouly. |
| 250 ThreadPostingAndRunningTask thread_running_task( | 273 ThreadPostingAndRunningTask thread_running_task( |
| 251 &tracker_, &blocked_task, ThreadPostingAndRunningTask::Action::RUN, | 274 &tracker_, std::move(blocked_task), |
| 252 false); | 275 ThreadPostingAndRunningTask::Action::RUN, false); |
| 253 thread_running_task.Start(); | 276 thread_running_task.Start(); |
| 254 | 277 |
| 255 // Initiate shutdown while the task is running. | 278 // Initiate shutdown while the task is running. |
| 256 CallShutdownAsync(); | 279 CallShutdownAsync(); |
| 257 | 280 |
| 258 if (GetParam() == TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) { | 281 if (GetParam() == TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) { |
| 259 // Shutdown should complete even with a CONTINUE_ON_SHUTDOWN in progress. | 282 // Shutdown should complete even with a CONTINUE_ON_SHUTDOWN in progress. |
| 260 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 283 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 261 } else { | 284 } else { |
| 262 // Shutdown should block with any non CONTINUE_ON_SHUTDOWN task in progress. | 285 // Shutdown should block with any non CONTINUE_ON_SHUTDOWN task in progress. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 284 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 307 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
| 285 | 308 |
| 286 // Call Shutdown() asynchronously. | 309 // Call Shutdown() asynchronously. |
| 287 CallShutdownAsync(); | 310 CallShutdownAsync(); |
| 288 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 311 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 289 | 312 |
| 290 // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it | 313 // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it |
| 291 // should be discarded. | 314 // should be discarded. |
| 292 EXPECT_EQ(0U, NumTasksExecuted()); | 315 EXPECT_EQ(0U, NumTasksExecuted()); |
| 293 const bool should_run = GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN; | 316 const bool should_run = GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN; |
| 294 EXPECT_EQ(should_run, tracker_.RunTask(task.get(), SequenceToken::Create())); | 317 EXPECT_EQ(should_run, |
| 318 tracker_.RunTask(std::move(task), SequenceToken::Create())); |
| 295 EXPECT_EQ(should_run ? 1U : 0U, NumTasksExecuted()); | 319 EXPECT_EQ(should_run ? 1U : 0U, NumTasksExecuted()); |
| 296 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 320 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 297 | 321 |
| 298 // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. | 322 // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. |
| 299 EXPECT_TRUE( | 323 EXPECT_TRUE(tracker_.RunTask(std::move(block_shutdown_task), |
| 300 tracker_.RunTask(block_shutdown_task.get(), SequenceToken::Create())); | 324 SequenceToken::Create())); |
| 301 EXPECT_EQ(should_run ? 2U : 1U, NumTasksExecuted()); | 325 EXPECT_EQ(should_run ? 2U : 1U, NumTasksExecuted()); |
| 302 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 326 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 303 } | 327 } |
| 304 | 328 |
| 305 TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { | 329 TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { |
| 306 // Inform |task_tracker_| that a task will be posted. | 330 // Inform |task_tracker_| that a task will be posted. |
| 307 std::unique_ptr<Task> task(CreateTask(GetParam())); | 331 std::unique_ptr<Task> task(CreateTask(GetParam())); |
| 308 EXPECT_TRUE(tracker_.WillPostTask(task.get())); | 332 EXPECT_TRUE(tracker_.WillPostTask(task.get())); |
| 309 | 333 |
| 310 // Call Shutdown() asynchronously. | 334 // Call Shutdown() asynchronously. |
| 311 CallShutdownAsync(); | 335 CallShutdownAsync(); |
| 312 EXPECT_EQ(0U, NumTasksExecuted()); | 336 EXPECT_EQ(0U, NumTasksExecuted()); |
| 313 | 337 |
| 314 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { | 338 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { |
| 315 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 339 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 316 | 340 |
| 317 // Run the task to unblock shutdown. | 341 // Run the task to unblock shutdown. |
| 318 EXPECT_TRUE(tracker_.RunTask(task.get(), SequenceToken::Create())); | 342 EXPECT_TRUE(tracker_.RunTask(std::move(task), SequenceToken::Create())); |
| 319 EXPECT_EQ(1U, NumTasksExecuted()); | 343 EXPECT_EQ(1U, NumTasksExecuted()); |
| 320 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 344 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 321 | 345 |
| 322 // It is not possible to test running a BLOCK_SHUTDOWN task posted before | 346 // It is not possible to test running a BLOCK_SHUTDOWN task posted before |
| 323 // shutdown after shutdown because Shutdown() won't return if there are | 347 // shutdown after shutdown because Shutdown() won't return if there are |
| 324 // pending BLOCK_SHUTDOWN tasks. | 348 // pending BLOCK_SHUTDOWN tasks. |
| 325 } else { | 349 } else { |
| 326 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 350 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 327 | 351 |
| 328 // The task shouldn't be allowed to run after shutdown. | 352 // The task shouldn't be allowed to run after shutdown. |
| 329 EXPECT_FALSE(tracker_.RunTask(task.get(), SequenceToken::Create())); | 353 EXPECT_FALSE(tracker_.RunTask(std::move(task), SequenceToken::Create())); |
| 330 EXPECT_EQ(0U, NumTasksExecuted()); | 354 EXPECT_EQ(0U, NumTasksExecuted()); |
| 331 } | 355 } |
| 332 } | 356 } |
| 333 | 357 |
| 334 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { | 358 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { |
| 335 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to | 359 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to |
| 336 // block shutdown. | 360 // block shutdown. |
| 337 std::unique_ptr<Task> block_shutdown_task( | 361 std::unique_ptr<Task> block_shutdown_task( |
| 338 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 362 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 339 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 363 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
| 340 | 364 |
| 341 // Call Shutdown() asynchronously. | 365 // Call Shutdown() asynchronously. |
| 342 CallShutdownAsync(); | 366 CallShutdownAsync(); |
| 343 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 367 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 344 | 368 |
| 345 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { | 369 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { |
| 346 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted. | 370 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted. |
| 347 std::unique_ptr<Task> task(CreateTask(GetParam())); | 371 std::unique_ptr<Task> task(CreateTask(GetParam())); |
| 348 EXPECT_TRUE(tracker_.WillPostTask(task.get())); | 372 EXPECT_TRUE(tracker_.WillPostTask(task.get())); |
| 349 | 373 |
| 350 // Run the BLOCK_SHUTDOWN task. | 374 // Run the BLOCK_SHUTDOWN task. |
| 351 EXPECT_EQ(0U, NumTasksExecuted()); | 375 EXPECT_EQ(0U, NumTasksExecuted()); |
| 352 EXPECT_TRUE(tracker_.RunTask(task.get(), SequenceToken::Create())); | 376 EXPECT_TRUE(tracker_.RunTask(std::move(task), SequenceToken::Create())); |
| 353 EXPECT_EQ(1U, NumTasksExecuted()); | 377 EXPECT_EQ(1U, NumTasksExecuted()); |
| 354 } else { | 378 } else { |
| 355 // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task. | 379 // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task. |
| 356 std::unique_ptr<Task> task(CreateTask(GetParam())); | 380 std::unique_ptr<Task> task(CreateTask(GetParam())); |
| 357 EXPECT_FALSE(tracker_.WillPostTask(task.get())); | 381 EXPECT_FALSE(tracker_.WillPostTask(task.get())); |
| 358 | 382 |
| 359 // Don't try to run the task, because it wasn't allowed to be posted. | 383 // Don't try to run the task, because it wasn't allowed to be posted. |
| 360 } | 384 } |
| 361 | 385 |
| 362 // Unblock shutdown by running |block_shutdown_task|. | 386 // Unblock shutdown by running |block_shutdown_task|. |
| 363 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 387 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 364 EXPECT_TRUE( | 388 EXPECT_TRUE(tracker_.RunTask(std::move(block_shutdown_task), |
| 365 tracker_.RunTask(block_shutdown_task.get(), SequenceToken::Create())); | 389 SequenceToken::Create())); |
| 366 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, | 390 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
| 367 NumTasksExecuted()); | 391 NumTasksExecuted()); |
| 368 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 392 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 369 } | 393 } |
| 370 | 394 |
| 371 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAfterShutdown) { | 395 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAfterShutdown) { |
| 372 tracker_.Shutdown(); | 396 tracker_.Shutdown(); |
| 373 | 397 |
| 374 std::unique_ptr<Task> task(CreateTask(GetParam())); | 398 std::unique_ptr<Task> task(CreateTask(GetParam())); |
| 375 | 399 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 393 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 417 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
| 394 EXPECT_TRUE(tracker.WillPostTask(task.get())); | 418 EXPECT_TRUE(tracker.WillPostTask(task.get())); |
| 395 | 419 |
| 396 // Set the singleton allowed bit to the opposite of what it is expected to be | 420 // Set the singleton allowed bit to the opposite of what it is expected to be |
| 397 // when |tracker| runs |task| to verify that |tracker| actually sets the | 421 // when |tracker| runs |task| to verify that |tracker| actually sets the |
| 398 // correct value. | 422 // correct value. |
| 399 ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons); | 423 ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons); |
| 400 | 424 |
| 401 // Running the task should fail iff the task isn't allowed to use singletons. | 425 // Running the task should fail iff the task isn't allowed to use singletons. |
| 402 if (can_use_singletons) { | 426 if (can_use_singletons) { |
| 403 EXPECT_TRUE(tracker.RunTask(task.get(), SequenceToken::Create())); | 427 EXPECT_TRUE(tracker.RunTask(std::move(task), SequenceToken::Create())); |
| 404 } else { | 428 } else { |
| 405 EXPECT_DCHECK_DEATH( | 429 EXPECT_DCHECK_DEATH( |
| 406 { tracker.RunTask(task.get(), SequenceToken::Create()); }); | 430 { tracker.RunTask(std::move(task), SequenceToken::Create()); }); |
| 407 } | 431 } |
| 408 } | 432 } |
| 409 | 433 |
| 410 static void RunTaskRunnerHandleVerificationTask( | 434 static void RunTaskRunnerHandleVerificationTask( |
| 411 TaskTracker* tracker, | 435 TaskTracker* tracker, |
| 412 std::unique_ptr<Task> verify_task) { | 436 std::unique_ptr<Task> verify_task) { |
| 413 // Pretend |verify_task| is posted to respect TaskTracker's contract. | 437 // Pretend |verify_task| is posted to respect TaskTracker's contract. |
| 414 EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); | 438 EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); |
| 415 | 439 |
| 416 // Confirm that the test conditions are right (no TaskRunnerHandles set | 440 // Confirm that the test conditions are right (no TaskRunnerHandles set |
| 417 // already). | 441 // already). |
| 418 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 442 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
| 419 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 443 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
| 420 | 444 |
| 421 EXPECT_TRUE(tracker->RunTask(verify_task.get(), SequenceToken::Create())); | 445 EXPECT_TRUE( |
| 446 tracker->RunTask(std::move(verify_task), SequenceToken::Create())); |
| 422 | 447 |
| 423 // TaskRunnerHandle state is reset outside of task's scope. | 448 // TaskRunnerHandle state is reset outside of task's scope. |
| 424 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 449 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
| 425 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 450 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
| 426 } | 451 } |
| 427 | 452 |
| 428 static void VerifyNoTaskRunnerHandle() { | 453 static void VerifyNoTaskRunnerHandle() { |
| 429 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 454 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
| 430 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 455 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
| 431 } | 456 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingDelayedTask) { | 516 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingDelayedTask) { |
| 492 const Task delayed_task(FROM_HERE, Bind(&DoNothing), | 517 const Task delayed_task(FROM_HERE, Bind(&DoNothing), |
| 493 TaskTraits().WithShutdownBehavior(GetParam()), | 518 TaskTraits().WithShutdownBehavior(GetParam()), |
| 494 TimeDelta::FromDays(1)); | 519 TimeDelta::FromDays(1)); |
| 495 tracker_.WillPostTask(&delayed_task); | 520 tracker_.WillPostTask(&delayed_task); |
| 496 // Flush() should return even if the delayed task didn't run. | 521 // Flush() should return even if the delayed task didn't run. |
| 497 tracker_.Flush(); | 522 tracker_.Flush(); |
| 498 } | 523 } |
| 499 | 524 |
| 500 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingUndelayedTask) { | 525 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingUndelayedTask) { |
| 501 const Task undelayed_task(FROM_HERE, Bind(&DoNothing), | 526 auto undelayed_task = base::MakeUnique<Task>( |
| 502 TaskTraits().WithShutdownBehavior(GetParam()), | 527 FROM_HERE, Bind(&DoNothing), |
| 503 TimeDelta()); | 528 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 504 tracker_.WillPostTask(&undelayed_task); | 529 tracker_.WillPostTask(undelayed_task.get()); |
| 505 | 530 |
| 506 // Flush() shouldn't return before the undelayed task runs. | 531 // Flush() shouldn't return before the undelayed task runs. |
| 507 CallFlushAsync(); | 532 CallFlushAsync(); |
| 508 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 533 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 509 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 534 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
| 510 | 535 |
| 511 // Flush() should return after the undelayed task runs. | 536 // Flush() should return after the undelayed task runs. |
| 512 tracker_.RunTask(&undelayed_task, SequenceToken::Create()); | 537 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); |
| 513 WAIT_FOR_ASYNC_FLUSH_RETURNED(); | 538 WAIT_FOR_ASYNC_FLUSH_RETURNED(); |
| 514 } | 539 } |
| 515 | 540 |
| 516 TEST_P(TaskSchedulerTaskTrackerTest, PostTaskDuringFlush) { | 541 TEST_P(TaskSchedulerTaskTrackerTest, PostTaskDuringFlush) { |
| 517 const Task undelayed_task(FROM_HERE, Bind(&DoNothing), | 542 auto undelayed_task = base::MakeUnique<Task>( |
| 518 TaskTraits().WithShutdownBehavior(GetParam()), | 543 FROM_HERE, Bind(&DoNothing), |
| 519 TimeDelta()); | 544 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 520 tracker_.WillPostTask(&undelayed_task); | 545 tracker_.WillPostTask(undelayed_task.get()); |
| 521 | 546 |
| 522 // Flush() shouldn't return before the undelayed task runs. | 547 // Flush() shouldn't return before the undelayed task runs. |
| 523 CallFlushAsync(); | 548 CallFlushAsync(); |
| 524 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 549 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 525 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 550 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
| 526 | 551 |
| 527 // Simulate posting another undelayed task. | 552 // Simulate posting another undelayed task. |
| 528 const Task other_undelayed_task(FROM_HERE, Bind(&DoNothing), | 553 auto other_undelayed_task = base::MakeUnique<Task>( |
| 529 TaskTraits().WithShutdownBehavior(GetParam()), | 554 FROM_HERE, Bind(&DoNothing), |
| 530 TimeDelta()); | 555 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 531 tracker_.WillPostTask(&other_undelayed_task); | 556 tracker_.WillPostTask(other_undelayed_task.get()); |
| 532 | 557 |
| 533 // Run the first undelayed task. | 558 // Run the first undelayed task. |
| 534 tracker_.RunTask(&undelayed_task, SequenceToken::Create()); | 559 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); |
| 535 | 560 |
| 536 // Flush() shouldn't return before the second undelayed task runs. | 561 // Flush() shouldn't return before the second undelayed task runs. |
| 537 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 562 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 538 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 563 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
| 539 | 564 |
| 540 // Flush() should return after the second undelayed task runs. | 565 // Flush() should return after the second undelayed task runs. |
| 541 tracker_.RunTask(&other_undelayed_task, SequenceToken::Create()); | 566 tracker_.RunTask(std::move(other_undelayed_task), SequenceToken::Create()); |
| 542 WAIT_FOR_ASYNC_FLUSH_RETURNED(); | 567 WAIT_FOR_ASYNC_FLUSH_RETURNED(); |
| 543 } | 568 } |
| 544 | 569 |
| 545 TEST_P(TaskSchedulerTaskTrackerTest, RunDelayedTaskDuringFlush) { | 570 TEST_P(TaskSchedulerTaskTrackerTest, RunDelayedTaskDuringFlush) { |
| 546 // Simulate posting a delayed and an undelayed task. | 571 // Simulate posting a delayed and an undelayed task. |
| 547 const Task delayed_task(FROM_HERE, Bind(&DoNothing), | 572 auto delayed_task = base::MakeUnique<Task>( |
| 548 TaskTraits().WithShutdownBehavior(GetParam()), | 573 FROM_HERE, Bind(&DoNothing), |
| 549 TimeDelta::FromDays(1)); | 574 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta::FromDays(1)); |
| 550 tracker_.WillPostTask(&delayed_task); | 575 tracker_.WillPostTask(delayed_task.get()); |
| 551 const Task undelayed_task(FROM_HERE, Bind(&DoNothing), | 576 auto undelayed_task = base::MakeUnique<Task>( |
| 552 TaskTraits().WithShutdownBehavior(GetParam()), | 577 FROM_HERE, Bind(&DoNothing), |
| 553 TimeDelta()); | 578 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 554 tracker_.WillPostTask(&undelayed_task); | 579 tracker_.WillPostTask(undelayed_task.get()); |
| 555 | 580 |
| 556 // Flush() shouldn't return before the undelayed task runs. | 581 // Flush() shouldn't return before the undelayed task runs. |
| 557 CallFlushAsync(); | 582 CallFlushAsync(); |
| 558 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 583 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 559 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 584 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
| 560 | 585 |
| 561 // Run the delayed task. | 586 // Run the delayed task. |
| 562 tracker_.RunTask(&delayed_task, SequenceToken::Create()); | 587 tracker_.RunTask(std::move(delayed_task), SequenceToken::Create()); |
| 563 | 588 |
| 564 // Flush() shouldn't return since there is still a pending undelayed | 589 // Flush() shouldn't return since there is still a pending undelayed |
| 565 // task. | 590 // task. |
| 566 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 591 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 567 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 592 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
| 568 | 593 |
| 569 // Run the undelayed task. | 594 // Run the undelayed task. |
| 570 tracker_.RunTask(&undelayed_task, SequenceToken::Create()); | 595 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); |
| 571 | 596 |
| 572 // Flush() should now return. | 597 // Flush() should now return. |
| 573 WAIT_FOR_ASYNC_FLUSH_RETURNED(); | 598 WAIT_FOR_ASYNC_FLUSH_RETURNED(); |
| 574 } | 599 } |
| 575 | 600 |
| 576 TEST_P(TaskSchedulerTaskTrackerTest, FlushAfterShutdown) { | 601 TEST_P(TaskSchedulerTaskTrackerTest, FlushAfterShutdown) { |
| 577 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) | 602 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) |
| 578 return; | 603 return; |
| 579 | 604 |
| 580 // Simulate posting a task. | 605 // Simulate posting a task. |
| 581 const Task undelayed_task(FROM_HERE, Bind(&DoNothing), | 606 auto undelayed_task = base::MakeUnique<Task>( |
| 582 TaskTraits().WithShutdownBehavior(GetParam()), | 607 FROM_HERE, Bind(&DoNothing), |
| 583 TimeDelta()); | 608 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 584 tracker_.WillPostTask(&undelayed_task); | 609 tracker_.WillPostTask(undelayed_task.get()); |
| 585 | 610 |
| 586 // Shutdown() should return immediately since there are no pending | 611 // Shutdown() should return immediately since there are no pending |
| 587 // BLOCK_SHUTDOWN tasks. | 612 // BLOCK_SHUTDOWN tasks. |
| 588 tracker_.Shutdown(); | 613 tracker_.Shutdown(); |
| 589 | 614 |
| 590 // Flush() should return immediately after shutdown, even if an | 615 // Flush() should return immediately after shutdown, even if an |
| 591 // undelayed task hasn't run. | 616 // undelayed task hasn't run. |
| 592 tracker_.Flush(); | 617 tracker_.Flush(); |
| 593 } | 618 } |
| 594 | 619 |
| 595 TEST_P(TaskSchedulerTaskTrackerTest, ShutdownDuringFlush) { | 620 TEST_P(TaskSchedulerTaskTrackerTest, ShutdownDuringFlush) { |
| 596 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) | 621 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) |
| 597 return; | 622 return; |
| 598 | 623 |
| 599 // Simulate posting a task. | 624 // Simulate posting a task. |
| 600 const Task undelayed_task(FROM_HERE, Bind(&DoNothing), | 625 auto undelayed_task = base::MakeUnique<Task>( |
| 601 TaskTraits().WithShutdownBehavior(GetParam()), | 626 FROM_HERE, Bind(&DoNothing), |
| 602 TimeDelta()); | 627 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| 603 tracker_.WillPostTask(&undelayed_task); | 628 tracker_.WillPostTask(undelayed_task.get()); |
| 604 | 629 |
| 605 // Flush() shouldn't return before the undelayed task runs or | 630 // Flush() shouldn't return before the undelayed task runs or |
| 606 // shutdown completes. | 631 // shutdown completes. |
| 607 CallFlushAsync(); | 632 CallFlushAsync(); |
| 608 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 633 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 609 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 634 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
| 610 | 635 |
| 611 // Shutdown() should return immediately since there are no pending | 636 // Shutdown() should return immediately since there are no pending |
| 612 // BLOCK_SHUTDOWN tasks. | 637 // BLOCK_SHUTDOWN tasks. |
| 613 tracker_.Shutdown(); | 638 tracker_.Shutdown(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 634 void ExpectSequenceToken(SequenceToken sequence_token) { | 659 void ExpectSequenceToken(SequenceToken sequence_token) { |
| 635 EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread()); | 660 EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread()); |
| 636 } | 661 } |
| 637 | 662 |
| 638 } // namespace | 663 } // namespace |
| 639 | 664 |
| 640 // Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token | 665 // Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token |
| 641 // when a Task runs. | 666 // when a Task runs. |
| 642 TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { | 667 TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { |
| 643 const SequenceToken sequence_token(SequenceToken::Create()); | 668 const SequenceToken sequence_token(SequenceToken::Create()); |
| 644 Task task(FROM_HERE, Bind(&ExpectSequenceToken, sequence_token), TaskTraits(), | 669 auto task = base::MakeUnique<Task>(FROM_HERE, |
| 645 TimeDelta()); | 670 Bind(&ExpectSequenceToken, sequence_token), |
| 646 tracker_.WillPostTask(&task); | 671 TaskTraits(), TimeDelta()); |
| 672 tracker_.WillPostTask(task.get()); |
| 647 | 673 |
| 648 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 674 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
| 649 EXPECT_TRUE(tracker_.RunTask(&task, sequence_token)); | 675 EXPECT_TRUE(tracker_.RunTask(std::move(task), sequence_token)); |
| 650 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 676 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
| 651 } | 677 } |
| 652 | 678 |
| 653 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { | 679 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
| 654 // Post and run tasks asynchronously. | 680 // Post and run tasks asynchronously. |
| 655 std::vector<std::unique_ptr<Task>> tasks; | |
| 656 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 681 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| 657 | 682 |
| 658 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 683 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 659 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
| 660 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 684 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 661 &tracker_, tasks.back().get(), | 685 &tracker_, CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), |
| 662 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); | 686 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 663 threads.back()->Start(); | 687 threads.back()->Start(); |
| 664 | 688 |
| 665 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
| 666 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 689 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 667 &tracker_, tasks.back().get(), | 690 &tracker_, CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN), |
| 668 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); | 691 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 669 threads.back()->Start(); | 692 threads.back()->Start(); |
| 670 | 693 |
| 671 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
| 672 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 694 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 673 &tracker_, tasks.back().get(), | 695 &tracker_, CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN), |
| 674 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); | 696 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 675 threads.back()->Start(); | 697 threads.back()->Start(); |
| 676 } | 698 } |
| 677 | 699 |
| 678 for (const auto& thread : threads) | 700 for (const auto& thread : threads) |
| 679 thread->Join(); | 701 thread->Join(); |
| 680 | 702 |
| 681 // Expect all tasks to be executed. | 703 // Expect all tasks to be executed. |
| 682 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); | 704 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); |
| 683 | 705 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 713 | 735 |
| 714 for (const auto& thread : post_threads) | 736 for (const auto& thread : post_threads) |
| 715 thread->Join(); | 737 thread->Join(); |
| 716 | 738 |
| 717 // Call Shutdown() asynchronously. | 739 // Call Shutdown() asynchronously. |
| 718 CallShutdownAsync(); | 740 CallShutdownAsync(); |
| 719 | 741 |
| 720 // Run tasks asynchronously. | 742 // Run tasks asynchronously. |
| 721 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; | 743 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; |
| 722 | 744 |
| 723 for (const auto& task : tasks) { | 745 for (auto& task : tasks) { |
| 724 run_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 746 run_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 725 &tracker_, task.get(), ThreadPostingAndRunningTask::Action::RUN, | 747 &tracker_, std::move(task), ThreadPostingAndRunningTask::Action::RUN, |
| 726 false)); | 748 false)); |
| 727 run_threads.back()->Start(); | 749 run_threads.back()->Start(); |
| 728 } | 750 } |
| 729 | 751 |
| 730 for (const auto& thread : run_threads) | 752 for (const auto& thread : run_threads) |
| 731 thread->Join(); | 753 thread->Join(); |
| 732 | 754 |
| 733 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 755 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 734 | 756 |
| 735 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 757 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
| 736 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 758 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
| 737 } | 759 } |
| 738 | 760 |
| 739 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { | 761 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
| 740 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to | 762 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to |
| 741 // block shutdown. | 763 // block shutdown. |
| 742 std::unique_ptr<Task> block_shutdown_task( | 764 std::unique_ptr<Task> block_shutdown_task( |
| 743 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 765 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 744 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 766 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
| 745 | 767 |
| 746 // Call Shutdown() asynchronously. | 768 // Call Shutdown() asynchronously. |
| 747 CallShutdownAsync(); | 769 CallShutdownAsync(); |
| 748 | 770 |
| 749 // Post and run tasks asynchronously. | 771 // Post and run tasks asynchronously. |
| 750 std::vector<std::unique_ptr<Task>> tasks; | |
| 751 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 772 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| 752 | 773 |
| 753 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 774 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 754 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
| 755 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 775 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 756 &tracker_, tasks.back().get(), | 776 &tracker_, CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), |
| 757 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); | 777 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); |
| 758 threads.back()->Start(); | 778 threads.back()->Start(); |
| 759 | 779 |
| 760 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
| 761 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 780 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 762 &tracker_, tasks.back().get(), | 781 &tracker_, CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN), |
| 763 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); | 782 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); |
| 764 threads.back()->Start(); | 783 threads.back()->Start(); |
| 765 | 784 |
| 766 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
| 767 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( | 785 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 768 &tracker_, tasks.back().get(), | 786 &tracker_, CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN), |
| 769 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); | 787 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 770 threads.back()->Start(); | 788 threads.back()->Start(); |
| 771 } | 789 } |
| 772 | 790 |
| 773 for (const auto& thread : threads) | 791 for (const auto& thread : threads) |
| 774 thread->Join(); | 792 thread->Join(); |
| 775 | 793 |
| 776 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 794 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
| 777 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 795 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
| 778 | 796 |
| 779 // Shutdown() shouldn't return before |block_shutdown_task| is executed. | 797 // Shutdown() shouldn't return before |block_shutdown_task| is executed. |
| 780 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 798 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 781 | 799 |
| 782 // Unblock shutdown by running |block_shutdown_task|. | 800 // Unblock shutdown by running |block_shutdown_task|. |
| 783 EXPECT_TRUE( | 801 EXPECT_TRUE(tracker_.RunTask(std::move(block_shutdown_task), |
| 784 tracker_.RunTask(block_shutdown_task.get(), SequenceToken::Create())); | 802 SequenceToken::Create())); |
| 785 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); | 803 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); |
| 786 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 804 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 787 } | 805 } |
| 788 | 806 |
| 789 } // namespace internal | 807 } // namespace internal |
| 790 } // namespace base | 808 } // namespace base |
| OLD | NEW |