| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); | 559 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); |
| 560 } | 560 } |
| 561 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 561 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
| 562 | 562 |
| 563 // Queue up shutdown blocking tasks behind those which will attempt to post | 563 // Queue up shutdown blocking tasks behind those which will attempt to post |
| 564 // additional tasks when run, PostAdditionalTasks attemtps to post 3 | 564 // additional tasks when run, PostAdditionalTasks attemtps to post 3 |
| 565 // new FastTasks, one for each shutdown_behavior. | 565 // new FastTasks, one for each shutdown_behavior. |
| 566 const int kNumQueuedTasks = static_cast<int>(kNumWorkerThreads); | 566 const int kNumQueuedTasks = static_cast<int>(kNumWorkerThreads); |
| 567 for (int i = 0; i < kNumQueuedTasks; ++i) { | 567 for (int i = 0; i < kNumQueuedTasks; ++i) { |
| 568 EXPECT_TRUE(pool()->PostWorkerTaskWithShutdownBehavior( | 568 EXPECT_TRUE(pool()->PostWorkerTaskWithShutdownBehavior( |
| 569 FROM_HERE, | 569 FROM_HERE, base::Bind(&TestTracker::PostAdditionalTasks, tracker(), i, |
| 570 base::Bind(&TestTracker::PostAdditionalTasks, tracker(), i, pool(), | 570 base::RetainedRef(pool()), false), |
| 571 false), | |
| 572 SequencedWorkerPool::BLOCK_SHUTDOWN)); | 571 SequencedWorkerPool::BLOCK_SHUTDOWN)); |
| 573 } | 572 } |
| 574 | 573 |
| 575 // Setup to open the floodgates from within Shutdown(). | 574 // Setup to open the floodgates from within Shutdown(). |
| 576 SetWillWaitForShutdownCallback( | 575 SetWillWaitForShutdownCallback( |
| 577 base::Bind(&EnsureTasksToCompleteCountAndUnblock, | 576 base::Bind(&EnsureTasksToCompleteCountAndUnblock, |
| 578 scoped_refptr<TestTracker>(tracker()), | 577 scoped_refptr<TestTracker>(tracker()), |
| 579 0, &blocker, kNumBlockTasks)); | 578 0, &blocker, kNumBlockTasks)); |
| 580 | 579 |
| 581 // Allow half of the additional blocking tasks thru. | 580 // Allow half of the additional blocking tasks thru. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token)); | 800 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token)); |
| 802 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); | 801 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); |
| 803 EXPECT_FALSE( | 802 EXPECT_FALSE( |
| 804 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token1)); | 803 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token1)); |
| 805 EXPECT_FALSE( | 804 EXPECT_FALSE( |
| 806 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token2)); | 805 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token2)); |
| 807 EXPECT_FALSE(unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread( | 806 EXPECT_FALSE(unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread( |
| 808 unsequenced_token)); | 807 unsequenced_token)); |
| 809 | 808 |
| 810 pool()->PostSequencedWorkerTask( | 809 pool()->PostSequencedWorkerTask( |
| 811 token1, FROM_HERE, base::Bind(&IsRunningOnCurrentThreadTask, token1, | 810 token1, FROM_HERE, |
| 812 token2, pool(), unused_pool_owner.pool())); | 811 base::Bind(&IsRunningOnCurrentThreadTask, token1, token2, |
| 812 base::RetainedRef(pool()), |
| 813 base::RetainedRef(unused_pool_owner.pool()))); |
| 813 pool()->PostSequencedWorkerTask( | 814 pool()->PostSequencedWorkerTask( |
| 814 token2, FROM_HERE, | 815 token2, FROM_HERE, |
| 815 base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token, | 816 base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token, |
| 816 pool(), unused_pool_owner.pool())); | 817 base::RetainedRef(pool()), |
| 818 base::RetainedRef(unused_pool_owner.pool()))); |
| 817 pool()->PostWorkerTask( | 819 pool()->PostWorkerTask( |
| 818 FROM_HERE, base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, | 820 FROM_HERE, base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, |
| 819 token1, pool(), unused_pool_owner.pool())); | 821 token1, base::RetainedRef(pool()), |
| 822 base::RetainedRef(unused_pool_owner.pool()))); |
| 820 } | 823 } |
| 821 | 824 |
| 822 // Checks that tasks are destroyed in the right context during shutdown. If a | 825 // Checks that tasks are destroyed in the right context during shutdown. If a |
| 823 // task is destroyed while SequencedWorkerPool's global lock is held, | 826 // task is destroyed while SequencedWorkerPool's global lock is held, |
| 824 // SequencedWorkerPool might deadlock. | 827 // SequencedWorkerPool might deadlock. |
| 825 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { | 828 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { |
| 826 for (int i = 0; i < 4; ++i) { | 829 for (int i = 0; i < 4; ++i) { |
| 827 scoped_refptr<DestructionDeadlockChecker> checker( | 830 scoped_refptr<DestructionDeadlockChecker> checker( |
| 828 new DestructionDeadlockChecker(pool())); | 831 new DestructionDeadlockChecker(pool())); |
| 829 tracker()->PostRepostingTask(pool(), checker); | 832 tracker()->PostRepostingTask(pool(), checker); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 base::Bind(&TestTracker::FastTask, tracker(), 0), | 869 base::Bind(&TestTracker::FastTask, tracker(), 0), |
| 867 TimeDelta::FromMinutes(5)); | 870 TimeDelta::FromMinutes(5)); |
| 868 pool()->PostWorkerTask(FROM_HERE, | 871 pool()->PostWorkerTask(FROM_HERE, |
| 869 base::Bind(&TestTracker::SlowTask, tracker(), 0)); | 872 base::Bind(&TestTracker::SlowTask, tracker(), 0)); |
| 870 const size_t kNumFastTasks = 20; | 873 const size_t kNumFastTasks = 20; |
| 871 for (size_t i = 0; i < kNumFastTasks; i++) { | 874 for (size_t i = 0; i < kNumFastTasks; i++) { |
| 872 pool()->PostWorkerTask(FROM_HERE, | 875 pool()->PostWorkerTask(FROM_HERE, |
| 873 base::Bind(&TestTracker::FastTask, tracker(), 0)); | 876 base::Bind(&TestTracker::FastTask, tracker(), 0)); |
| 874 } | 877 } |
| 875 pool()->PostWorkerTask( | 878 pool()->PostWorkerTask( |
| 876 FROM_HERE, | 879 FROM_HERE, base::Bind(&TestTracker::PostAdditionalTasks, tracker(), 0, |
| 877 base::Bind(&TestTracker::PostAdditionalTasks, tracker(), 0, pool(), | 880 base::RetainedRef(pool()), true)); |
| 878 true)); | |
| 879 | 881 |
| 880 // We expect all except the delayed task to have been run. We verify all | 882 // We expect all except the delayed task to have been run. We verify all |
| 881 // closures have been deleted by looking at the refcount of the | 883 // closures have been deleted by looking at the refcount of the |
| 882 // tracker. | 884 // tracker. |
| 883 EXPECT_FALSE(tracker()->HasOneRef()); | 885 EXPECT_FALSE(tracker()->HasOneRef()); |
| 884 pool()->FlushForTesting(); | 886 pool()->FlushForTesting(); |
| 885 EXPECT_TRUE(tracker()->HasOneRef()); | 887 EXPECT_TRUE(tracker()->HasOneRef()); |
| 886 EXPECT_EQ(1 + kNumFastTasks + 1 + 3, tracker()->GetTasksCompletedCount()); | 888 EXPECT_EQ(1 + kNumFastTasks + 1 + 3, tracker()->GetTasksCompletedCount()); |
| 887 | 889 |
| 888 // Should be fine to call on an idle instance with all threads created, and | 890 // Should be fine to call on an idle instance with all threads created, and |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 // thread will start running tasks with this sequence token. | 944 // thread will start running tasks with this sequence token. |
| 943 const SequencedWorkerPool::SequenceToken sequence_token = | 945 const SequencedWorkerPool::SequenceToken sequence_token = |
| 944 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); | 946 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); |
| 945 ASSERT_TRUE(sequence_token.IsValid()); | 947 ASSERT_TRUE(sequence_token.IsValid()); |
| 946 EXPECT_TRUE(pool->IsRunningSequence(sequence_token)); | 948 EXPECT_TRUE(pool->IsRunningSequence(sequence_token)); |
| 947 | 949 |
| 948 // The two sequenced task runners should be the same. See | 950 // The two sequenced task runners should be the same. See |
| 949 // VerifyCurrentSequencedTaskRunner() above for why the check is implemented | 951 // VerifyCurrentSequencedTaskRunner() above for why the check is implemented |
| 950 // this way. | 952 // this way. |
| 951 const bool expected_equal = true; | 953 const bool expected_equal = true; |
| 952 task_runner->PostTask( | 954 task_runner->PostTask(FROM_HERE, |
| 953 FROM_HERE, | 955 Bind(&VerifySequencedTaskRunnerRunsOnCurrentThread, |
| 954 Bind(&VerifySequencedTaskRunnerRunsOnCurrentThread, | 956 RetainedRef(std::move(expected_task_runner)), |
| 955 std::move(expected_task_runner), expected_equal, callback)); | 957 expected_equal, callback)); |
| 956 } | 958 } |
| 957 | 959 |
| 958 TEST_F(SequencedWorkerPoolTest, GetSequencedTaskRunnerForCurrentThread) { | 960 TEST_F(SequencedWorkerPoolTest, GetSequencedTaskRunnerForCurrentThread) { |
| 959 EnsureAllWorkersCreated(); | 961 EnsureAllWorkersCreated(); |
| 960 | 962 |
| 961 // The current thread should not have a sequenced task runner from a | 963 // The current thread should not have a sequenced task runner from a |
| 962 // worker pool. | 964 // worker pool. |
| 963 scoped_refptr<SequencedTaskRunner> local_task_runner = | 965 scoped_refptr<SequencedTaskRunner> local_task_runner = |
| 964 SequencedWorkerPool::GetSequencedTaskRunnerForCurrentThread(); | 966 SequencedWorkerPool::GetSequencedTaskRunnerForCurrentThread(); |
| 965 EXPECT_FALSE(local_task_runner); | 967 EXPECT_FALSE(local_task_runner); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 979 base::Unretained(task_runner_2.get()), true, signal)); | 981 base::Unretained(task_runner_2.get()), true, signal)); |
| 980 event.Wait(); | 982 event.Wait(); |
| 981 | 983 |
| 982 task_runner_1->PostTask( | 984 task_runner_1->PostTask( |
| 983 FROM_HERE, Bind(&VerifyCurrentSequencedTaskRunner, | 985 FROM_HERE, Bind(&VerifyCurrentSequencedTaskRunner, |
| 984 base::Unretained(task_runner_2.get()), false, signal)); | 986 base::Unretained(task_runner_2.get()), false, signal)); |
| 985 event.Wait(); | 987 event.Wait(); |
| 986 | 988 |
| 987 pool()->PostWorkerTask( | 989 pool()->PostWorkerTask( |
| 988 FROM_HERE, Bind(&VerifyCurrentSequencedTaskRunnerForUnsequencedTask, | 990 FROM_HERE, Bind(&VerifyCurrentSequencedTaskRunnerForUnsequencedTask, |
| 989 pool(), signal)); | 991 RetainedRef(pool()), signal)); |
| 990 event.Wait(); | 992 event.Wait(); |
| 991 } | 993 } |
| 992 | 994 |
| 993 class ChecksSequenceOnDestruction | 995 class ChecksSequenceOnDestruction |
| 994 : public RefCountedThreadSafe<ChecksSequenceOnDestruction> { | 996 : public RefCountedThreadSafe<ChecksSequenceOnDestruction> { |
| 995 public: | 997 public: |
| 996 void DoNothing() {} | 998 void DoNothing() {} |
| 997 | 999 |
| 998 private: | 1000 private: |
| 999 friend class RefCountedThreadSafe<ChecksSequenceOnDestruction>; | 1001 friend class RefCountedThreadSafe<ChecksSequenceOnDestruction>; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, | 1160 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, |
| 1159 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1161 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
| 1160 INSTANTIATE_TYPED_TEST_CASE_P( | 1162 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1161 SequencedWorkerPoolSequencedTaskRunner, | 1163 SequencedWorkerPoolSequencedTaskRunner, |
| 1162 SequencedTaskRunnerDelayedTest, | 1164 SequencedTaskRunnerDelayedTest, |
| 1163 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1165 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
| 1164 | 1166 |
| 1165 } // namespace | 1167 } // namespace |
| 1166 | 1168 |
| 1167 } // namespace base | 1169 } // namespace base |
| OLD | NEW |