| 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 |