Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(891)

Side by Side Diff: base/threading/sequenced_worker_pool_unittest.cc

Issue 988693005: Chromium roll (https://codereview.chromium.org/976353002) (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fixed bad android build patch Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/threading/sequenced_worker_pool.cc ('k') | base/threading/thread_restrictions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 cond_var_.Signal(); 60 cond_var_.Signal();
61 } 61 }
62 62
63 private: 63 private:
64 base::Lock lock_; 64 base::Lock lock_;
65 base::ConditionVariable cond_var_; 65 base::ConditionVariable cond_var_;
66 66
67 size_t unblock_counter_; 67 size_t unblock_counter_;
68 }; 68 };
69 69
70 class DestructionDeadlockChecker
71 : public base::RefCountedThreadSafe<DestructionDeadlockChecker> {
72 public:
73 DestructionDeadlockChecker(const scoped_refptr<SequencedWorkerPool>& pool)
74 : pool_(pool) {}
75
76 protected:
77 virtual ~DestructionDeadlockChecker() {
78 // This method should not deadlock.
79 pool_->RunsTasksOnCurrentThread();
80 }
81
82 private:
83 scoped_refptr<SequencedWorkerPool> pool_;
84 friend class base::RefCountedThreadSafe<DestructionDeadlockChecker>;
85 };
86
70 class TestTracker : public base::RefCountedThreadSafe<TestTracker> { 87 class TestTracker : public base::RefCountedThreadSafe<TestTracker> {
71 public: 88 public:
72 TestTracker() 89 TestTracker()
73 : lock_(), 90 : lock_(),
74 cond_var_(&lock_), 91 cond_var_(&lock_),
75 started_events_(0) { 92 started_events_(0) {
76 } 93 }
77 94
78 // Each of these tasks appends the argument to the complete sequence vector 95 // Each of these tasks appends the argument to the complete sequence vector
79 // so calling code can see what order they finished in. 96 // so calling code can see what order they finished in.
(...skipping 30 matching lines...) Expand all
110 EXPECT_EQ(expected_return_value, 127 EXPECT_EQ(expected_return_value,
111 pool->PostWorkerTaskWithShutdownBehavior( 128 pool->PostWorkerTaskWithShutdownBehavior(
112 FROM_HERE, fast_task, 129 FROM_HERE, fast_task,
113 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 130 SequencedWorkerPool::SKIP_ON_SHUTDOWN));
114 pool->PostWorkerTaskWithShutdownBehavior( 131 pool->PostWorkerTaskWithShutdownBehavior(
115 FROM_HERE, fast_task, 132 FROM_HERE, fast_task,
116 SequencedWorkerPool::BLOCK_SHUTDOWN); 133 SequencedWorkerPool::BLOCK_SHUTDOWN);
117 SignalWorkerDone(id); 134 SignalWorkerDone(id);
118 } 135 }
119 136
137 // This task posts itself back onto the SequencedWorkerPool before it
138 // finishes running. Each instance of the task maintains a strong reference
139 // to a DestructionDeadlockChecker. The DestructionDeadlockChecker is only
140 // destroyed when the task is destroyed without being run, which only happens
141 // during destruction of the SequencedWorkerPool.
142 void PostRepostingTask(
143 const scoped_refptr<SequencedWorkerPool>& pool,
144 const scoped_refptr<DestructionDeadlockChecker>& checker) {
145 Closure reposting_task =
146 base::Bind(&TestTracker::PostRepostingTask, this, pool, checker);
147 pool->PostWorkerTaskWithShutdownBehavior(
148 FROM_HERE, reposting_task, SequencedWorkerPool::SKIP_ON_SHUTDOWN);
149 }
150
120 // Waits until the given number of tasks have started executing. 151 // Waits until the given number of tasks have started executing.
121 void WaitUntilTasksBlocked(size_t count) { 152 void WaitUntilTasksBlocked(size_t count) {
122 { 153 {
123 base::AutoLock lock(lock_); 154 base::AutoLock lock(lock_);
124 while (started_events_ < count) 155 while (started_events_ < count)
125 cond_var_.Wait(); 156 cond_var_.Wait();
126 } 157 }
127 cond_var_.Signal(); 158 cond_var_.Signal();
128 } 159 }
129 160
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 base::Bind(&IsRunningOnCurrentThreadTask, 773 base::Bind(&IsRunningOnCurrentThreadTask,
743 token2, unsequenced_token, pool(), unused_pool)); 774 token2, unsequenced_token, pool(), unused_pool));
744 pool()->PostWorkerTask( 775 pool()->PostWorkerTask(
745 FROM_HERE, 776 FROM_HERE,
746 base::Bind(&IsRunningOnCurrentThreadTask, 777 base::Bind(&IsRunningOnCurrentThreadTask,
747 unsequenced_token, token1, pool(), unused_pool)); 778 unsequenced_token, token1, pool(), unused_pool));
748 pool()->Shutdown(); 779 pool()->Shutdown();
749 unused_pool->Shutdown(); 780 unused_pool->Shutdown();
750 } 781 }
751 782
783 // Checks that tasks are destroyed in the right context during shutdown. If a
784 // task is destroyed while SequencedWorkerPool's global lock is held,
785 // SequencedWorkerPool might deadlock.
786 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
787 for (int i = 0; i < 4; ++i) {
788 scoped_refptr<DestructionDeadlockChecker> checker(
789 new DestructionDeadlockChecker(pool()));
790 tracker()->PostRepostingTask(pool(), checker);
791 }
792
793 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
794 // which in turn should not deadlock in their destructors.
795 pool()->Shutdown();
796 }
797
752 // Verify that FlushForTesting works as intended. 798 // Verify that FlushForTesting works as intended.
753 TEST_F(SequencedWorkerPoolTest, FlushForTesting) { 799 TEST_F(SequencedWorkerPoolTest, FlushForTesting) {
754 // Should be fine to call on a new instance. 800 // Should be fine to call on a new instance.
755 pool()->FlushForTesting(); 801 pool()->FlushForTesting();
756 802
757 // Queue up a bunch of work, including a long delayed task and 803 // Queue up a bunch of work, including a long delayed task and
758 // a task that produces additional tasks as an artifact. 804 // a task that produces additional tasks as an artifact.
759 pool()->PostDelayedWorkerTask( 805 pool()->PostDelayedWorkerTask(
760 FROM_HERE, 806 FROM_HERE,
761 base::Bind(&TestTracker::FastTask, tracker(), 0), 807 base::Bind(&TestTracker::FastTask, tracker(), 0),
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, 955 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest,
910 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 956 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
911 957
912 INSTANTIATE_TYPED_TEST_CASE_P( 958 INSTANTIATE_TYPED_TEST_CASE_P(
913 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, 959 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest,
914 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 960 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
915 961
916 } // namespace 962 } // namespace
917 963
918 } // namespace base 964 } // namespace base
OLDNEW
« no previous file with comments | « base/threading/sequenced_worker_pool.cc ('k') | base/threading/thread_restrictions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698