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 |