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