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 <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 19 matching lines...) Expand all Loading... |
30 // mark as flaky if they're hanging, it's likely an actual bug. | 30 // mark as flaky if they're hanging, it's likely an actual bug. |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 const size_t kNumWorkerThreads = 3; | 34 const size_t kNumWorkerThreads = 3; |
35 | 35 |
36 // Allows a number of threads to all be blocked on the same event, and | 36 // Allows a number of threads to all be blocked on the same event, and |
37 // provides a way to unblock a certain number of them. | 37 // provides a way to unblock a certain number of them. |
38 class ThreadBlocker { | 38 class ThreadBlocker { |
39 public: | 39 public: |
40 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) { | 40 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) {} |
41 } | |
42 | 41 |
43 void Block() { | 42 void Block() { |
44 { | 43 { |
45 base::AutoLock lock(lock_); | 44 base::AutoLock lock(lock_); |
46 while (unblock_counter_ == 0) | 45 while (unblock_counter_ == 0) |
47 cond_var_.Wait(); | 46 cond_var_.Wait(); |
48 unblock_counter_--; | 47 unblock_counter_--; |
49 } | 48 } |
50 cond_var_.Signal(); | 49 cond_var_.Signal(); |
51 } | 50 } |
(...skipping 20 matching lines...) Expand all Loading... |
72 : lock_(), | 71 : lock_(), |
73 cond_var_(&lock_), | 72 cond_var_(&lock_), |
74 started_events_(0) { | 73 started_events_(0) { |
75 } | 74 } |
76 | 75 |
77 // Each of these tasks appends the argument to the complete sequence vector | 76 // Each of these tasks appends the argument to the complete sequence vector |
78 // so calling code can see what order they finished in. | 77 // so calling code can see what order they finished in. |
79 void FastTask(int id) { | 78 void FastTask(int id) { |
80 SignalWorkerDone(id); | 79 SignalWorkerDone(id); |
81 } | 80 } |
| 81 |
82 void SlowTask(int id) { | 82 void SlowTask(int id) { |
83 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); | 83 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); |
84 SignalWorkerDone(id); | 84 SignalWorkerDone(id); |
85 } | 85 } |
86 | 86 |
87 void BlockTask(int id, ThreadBlocker* blocker) { | 87 void BlockTask(int id, ThreadBlocker* blocker) { |
88 // Note that this task has started and signal anybody waiting for that | 88 // Note that this task has started and signal anybody waiting for that |
89 // to happen. | 89 // to happen. |
90 { | 90 { |
91 base::AutoLock lock(lock_); | 91 base::AutoLock lock(lock_); |
(...skipping 29 matching lines...) Expand all Loading... |
121 return ret; | 121 return ret; |
122 } | 122 } |
123 | 123 |
124 void ClearCompleteSequence() { | 124 void ClearCompleteSequence() { |
125 base::AutoLock lock(lock_); | 125 base::AutoLock lock(lock_); |
126 complete_sequence_.clear(); | 126 complete_sequence_.clear(); |
127 started_events_ = 0; | 127 started_events_ = 0; |
128 } | 128 } |
129 | 129 |
130 private: | 130 private: |
| 131 friend class base::RefCountedThreadSafe<TestTracker>; |
| 132 ~TestTracker() {} |
| 133 |
131 void SignalWorkerDone(int id) { | 134 void SignalWorkerDone(int id) { |
132 { | 135 { |
133 base::AutoLock lock(lock_); | 136 base::AutoLock lock(lock_); |
134 complete_sequence_.push_back(id); | 137 complete_sequence_.push_back(id); |
135 } | 138 } |
136 cond_var_.Signal(); | 139 cond_var_.Signal(); |
137 } | 140 } |
138 | 141 |
139 // Protects the complete_sequence. | 142 // Protects the complete_sequence. |
140 base::Lock lock_; | 143 base::Lock lock_; |
141 | 144 |
142 base::ConditionVariable cond_var_; | 145 base::ConditionVariable cond_var_; |
143 | 146 |
144 // Protected by lock_. | 147 // Protected by lock_. |
145 std::vector<int> complete_sequence_; | 148 std::vector<int> complete_sequence_; |
146 | 149 |
147 // Counter of the number of "block" workers that have started. | 150 // Counter of the number of "block" workers that have started. |
148 size_t started_events_; | 151 size_t started_events_; |
149 }; | 152 }; |
150 | 153 |
151 class SequencedWorkerPoolTest : public testing::Test { | 154 class SequencedWorkerPoolTest : public testing::Test { |
152 public: | 155 public: |
153 SequencedWorkerPoolTest() | 156 SequencedWorkerPoolTest() |
154 : pool_owner_(kNumWorkerThreads, "test"), | 157 : pool_owner_(kNumWorkerThreads, "test"), |
155 tracker_(new TestTracker) {} | 158 tracker_(new TestTracker) { |
| 159 } |
156 | 160 |
157 virtual ~SequencedWorkerPoolTest() {} | 161 virtual ~SequencedWorkerPoolTest() {} |
158 | 162 |
159 virtual void SetUp() OVERRIDE {} | 163 virtual void SetUp() OVERRIDE {} |
160 | 164 |
161 virtual void TearDown() OVERRIDE { | 165 virtual void TearDown() OVERRIDE { |
162 pool()->Shutdown(); | 166 pool()->Shutdown(); |
163 } | 167 } |
164 | 168 |
165 const scoped_refptr<SequencedWorkerPool>& pool() { | 169 const scoped_refptr<SequencedWorkerPool>& pool() { |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, | 640 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, |
637 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 641 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
638 | 642 |
639 INSTANTIATE_TYPED_TEST_CASE_P( | 643 INSTANTIATE_TYPED_TEST_CASE_P( |
640 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, | 644 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, |
641 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 645 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
642 | 646 |
643 } // namespace | 647 } // namespace |
644 | 648 |
645 } // namespace base | 649 } // namespace base |
OLD | NEW |