| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/threading/sequenced_worker_pool.h" | 5 #include "base/threading/sequenced_worker_pool.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 base::Bind(&TestTracker::FastTask, tracker(), 102), | 392 base::Bind(&TestTracker::FastTask, tracker(), 102), |
| 393 SequencedWorkerPool::BLOCK_SHUTDOWN); | 393 SequencedWorkerPool::BLOCK_SHUTDOWN); |
| 394 | 394 |
| 395 // Shutdown the worker pool. This should discard all non-blocking tasks. | 395 // Shutdown the worker pool. This should discard all non-blocking tasks. |
| 396 SetWillWaitForShutdownCallback( | 396 SetWillWaitForShutdownCallback( |
| 397 base::Bind(&EnsureTasksToCompleteCountAndUnblock, | 397 base::Bind(&EnsureTasksToCompleteCountAndUnblock, |
| 398 scoped_refptr<TestTracker>(tracker()), 0, | 398 scoped_refptr<TestTracker>(tracker()), 0, |
| 399 &blocker, kNumWorkerThreads)); | 399 &blocker, kNumWorkerThreads)); |
| 400 pool()->Shutdown(); | 400 pool()->Shutdown(); |
| 401 | 401 |
| 402 std::vector<int> result = tracker()->WaitUntilTasksComplete(4); | 402 std::vector<int> result = |
| 403 tracker()->WaitUntilTasksComplete(kNumWorkerThreads + 1); |
| 403 | 404 |
| 404 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN | 405 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN |
| 405 // one, in no particular order. | 406 // one, in no particular order. |
| 406 ASSERT_EQ(4u, result.size()); | 407 ASSERT_EQ(kNumWorkerThreads + 1, result.size()); |
| 407 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 408 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
| 408 EXPECT_TRUE(std::find(result.begin(), result.end(), static_cast<int>(i)) != | 409 EXPECT_TRUE(std::find(result.begin(), result.end(), static_cast<int>(i)) != |
| 409 result.end()); | 410 result.end()); |
| 410 } | 411 } |
| 411 EXPECT_TRUE(std::find(result.begin(), result.end(), 102) != result.end()); | 412 EXPECT_TRUE(std::find(result.begin(), result.end(), 102) != result.end()); |
| 412 } | 413 } |
| 413 | 414 |
| 414 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. | 415 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. |
| 415 TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) { | 416 TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) { |
| 416 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( | 417 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); | 452 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); |
| 452 EXPECT_FALSE(sequenced_runner->PostTask( | 453 EXPECT_FALSE(sequenced_runner->PostTask( |
| 453 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); | 454 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); |
| 454 | 455 |
| 455 // Continue the background thread and make sure the tasks can complete. | 456 // Continue the background thread and make sure the tasks can complete. |
| 456 blocker.Unblock(3); | 457 blocker.Unblock(3); |
| 457 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); | 458 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); |
| 458 EXPECT_EQ(3u, result.size()); | 459 EXPECT_EQ(3u, result.size()); |
| 459 } | 460 } |
| 460 | 461 |
| 462 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown |
| 463 // until they stop, but tasks not yet started do not. |
| 464 TEST_F(SequencedWorkerPoolTest, SkipOnShutdown) { |
| 465 // Start tasks to take all the threads and block them. |
| 466 EnsureAllWorkersCreated(); |
| 467 ThreadBlocker blocker; |
| 468 |
| 469 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not |
| 470 // return until these tasks have completed. |
| 471 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
| 472 pool()->PostWorkerTaskWithShutdownBehavior( |
| 473 FROM_HERE, |
| 474 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker), |
| 475 SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| 476 } |
| 477 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
| 478 |
| 479 // Now post an additional task as SKIP_ON_SHUTDOWN, which should not be |
| 480 // executed once Shutdown() has been called. |
| 481 pool()->PostWorkerTaskWithShutdownBehavior( |
| 482 FROM_HERE, |
| 483 base::Bind(&TestTracker::BlockTask, |
| 484 tracker(), 0, &blocker), |
| 485 SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| 486 |
| 487 // This callback will only be invoked if SKIP_ON_SHUTDOWN tasks that have |
| 488 // been started block shutdown. |
| 489 SetWillWaitForShutdownCallback( |
| 490 base::Bind(&EnsureTasksToCompleteCountAndUnblock, |
| 491 scoped_refptr<TestTracker>(tracker()), 0, |
| 492 &blocker, kNumWorkerThreads)); |
| 493 |
| 494 // No tasks should have completed yet. |
| 495 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size()); |
| 496 |
| 497 // This should not block. If this test hangs, it means it failed. |
| 498 pool()->Shutdown(); |
| 499 |
| 500 // Shutdown should not return until all of the tasks have completed. |
| 501 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumWorkerThreads)
; |
| 502 |
| 503 // Only taks marked SKIP_ON_SHUTDOWN that were already started should be |
| 504 // allowed to complete. No additional non-blocking tasks should have been |
| 505 // started. |
| 506 ASSERT_EQ(kNumWorkerThreads, result.size()); |
| 507 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
| 508 EXPECT_TRUE(std::find(result.begin(), result.end(), static_cast<int>(i)) != |
| 509 result.end()); |
| 510 } |
| 511 } |
| 512 |
| 461 // Ensure all worker threads are created, and then trigger a spurious | 513 // Ensure all worker threads are created, and then trigger a spurious |
| 462 // work signal. This shouldn't cause any other work signals to be | 514 // work signal. This shouldn't cause any other work signals to be |
| 463 // triggered. This is a regression test for http://crbug.com/117469. | 515 // triggered. This is a regression test for http://crbug.com/117469. |
| 464 TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) { | 516 TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) { |
| 465 EnsureAllWorkersCreated(); | 517 EnsureAllWorkersCreated(); |
| 466 int old_has_work_call_count = has_work_call_count(); | 518 int old_has_work_call_count = has_work_call_count(); |
| 467 pool()->SignalHasWorkForTesting(); | 519 pool()->SignalHasWorkForTesting(); |
| 468 // This is inherently racy, but can only produce false positives. | 520 // This is inherently racy, but can only produce false positives. |
| 469 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); | 521 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); |
| 470 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); | 522 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, | 692 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, |
| 641 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 693 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
| 642 | 694 |
| 643 INSTANTIATE_TYPED_TEST_CASE_P( | 695 INSTANTIATE_TYPED_TEST_CASE_P( |
| 644 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, | 696 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, |
| 645 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 697 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
| 646 | 698 |
| 647 } // namespace | 699 } // namespace |
| 648 | 700 |
| 649 } // namespace base | 701 } // namespace base |
| OLD | NEW |