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

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

Issue 7316015: Support Closure in ALL the loops! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix typo Created 9 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/worker_pool_posix.h" 5 #include "base/threading/worker_pool_posix.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/synchronization/condition_variable.h" 9 #include "base/synchronization/condition_variable.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "base/task.h" 11 #include "base/task.h"
12 #include "base/threading/platform_thread.h" 12 #include "base/threading/platform_thread.h"
13 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
14 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
15 15
16 namespace base { 16 namespace base {
17 17
18 // Peer class to provide passthrough access to PosixDynamicThreadPool internals. 18 // Peer class to provide passthrough access to PosixDynamicThreadPool internals.
19 class PosixDynamicThreadPool::PosixDynamicThreadPoolPeer { 19 class PosixDynamicThreadPool::PosixDynamicThreadPoolPeer {
20 public: 20 public:
21 explicit PosixDynamicThreadPoolPeer(PosixDynamicThreadPool* pool) 21 explicit PosixDynamicThreadPoolPeer(PosixDynamicThreadPool* pool)
22 : pool_(pool) {} 22 : pool_(pool) {}
23 23
24 Lock* lock() { return &pool_->lock_; } 24 Lock* lock() { return &pool_->lock_; }
25 ConditionVariable* tasks_available_cv() { 25 ConditionVariable* pending_tasks_available_cv() {
26 return &pool_->tasks_available_cv_; 26 return &pool_->pending_tasks_available_cv_;
27 } 27 }
28 const std::queue<Task*>& tasks() const { return pool_->tasks_; } 28 const std::queue<PendingTask>& pending_tasks() const {
29 return pool_->pending_tasks_;
30 }
29 int num_idle_threads() const { return pool_->num_idle_threads_; } 31 int num_idle_threads() const { return pool_->num_idle_threads_; }
30 ConditionVariable* num_idle_threads_cv() { 32 ConditionVariable* num_idle_threads_cv() {
31 return pool_->num_idle_threads_cv_.get(); 33 return pool_->num_idle_threads_cv_.get();
32 } 34 }
33 void set_num_idle_threads_cv(ConditionVariable* cv) { 35 void set_num_idle_threads_cv(ConditionVariable* cv) {
34 pool_->num_idle_threads_cv_.reset(cv); 36 pool_->num_idle_threads_cv_.reset(cv);
35 } 37 }
36 38
37 private: 39 private:
38 PosixDynamicThreadPool* pool_; 40 PosixDynamicThreadPool* pool_;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 int num_waiting_to_start_; 175 int num_waiting_to_start_;
174 ConditionVariable num_waiting_to_start_cv_; 176 ConditionVariable num_waiting_to_start_cv_;
175 base::WaitableEvent start_; 177 base::WaitableEvent start_;
176 }; 178 };
177 179
178 } // namespace 180 } // namespace
179 181
180 TEST_F(PosixDynamicThreadPoolTest, Basic) { 182 TEST_F(PosixDynamicThreadPoolTest, Basic) {
181 EXPECT_EQ(0, peer_.num_idle_threads()); 183 EXPECT_EQ(0, peer_.num_idle_threads());
182 EXPECT_EQ(0U, unique_threads_.size()); 184 EXPECT_EQ(0U, unique_threads_.size());
183 EXPECT_EQ(0U, peer_.tasks().size()); 185 EXPECT_EQ(0U, peer_.pending_tasks().size());
184 186
185 // Add one task and wait for it to be completed. 187 // Add one task and wait for it to be completed.
186 pool_->PostTask(CreateNewIncrementingTask()); 188 pool_->PostTask(FROM_HERE, CreateNewIncrementingTask());
187 189
188 WaitForIdleThreads(1); 190 WaitForIdleThreads(1);
189 191
190 EXPECT_EQ(1U, unique_threads_.size()) << 192 EXPECT_EQ(1U, unique_threads_.size()) <<
191 "There should be only one thread allocated for one task."; 193 "There should be only one thread allocated for one task.";
192 EXPECT_EQ(1, peer_.num_idle_threads()); 194 EXPECT_EQ(1, peer_.num_idle_threads());
193 EXPECT_EQ(1, counter_); 195 EXPECT_EQ(1, counter_);
194 } 196 }
195 197
196 TEST_F(PosixDynamicThreadPoolTest, ReuseIdle) { 198 TEST_F(PosixDynamicThreadPoolTest, ReuseIdle) {
197 // Add one task and wait for it to be completed. 199 // Add one task and wait for it to be completed.
198 pool_->PostTask(CreateNewIncrementingTask()); 200 pool_->PostTask(FROM_HERE, CreateNewIncrementingTask());
199 201
200 WaitForIdleThreads(1); 202 WaitForIdleThreads(1);
201 203
202 // Add another 2 tasks. One should reuse the existing worker thread. 204 // Add another 2 tasks. One should reuse the existing worker thread.
203 pool_->PostTask(CreateNewBlockingIncrementingTask()); 205 pool_->PostTask(FROM_HERE, CreateNewBlockingIncrementingTask());
204 pool_->PostTask(CreateNewBlockingIncrementingTask()); 206 pool_->PostTask(FROM_HERE, CreateNewBlockingIncrementingTask());
205 207
206 WaitForTasksToStart(2); 208 WaitForTasksToStart(2);
207 start_.Signal(); 209 start_.Signal();
208 WaitForIdleThreads(2); 210 WaitForIdleThreads(2);
209 211
210 EXPECT_EQ(2U, unique_threads_.size()); 212 EXPECT_EQ(2U, unique_threads_.size());
211 EXPECT_EQ(2, peer_.num_idle_threads()); 213 EXPECT_EQ(2, peer_.num_idle_threads());
212 EXPECT_EQ(3, counter_); 214 EXPECT_EQ(3, counter_);
213 } 215 }
214 216
215 TEST_F(PosixDynamicThreadPoolTest, TwoActiveTasks) { 217 TEST_F(PosixDynamicThreadPoolTest, TwoActiveTasks) {
216 // Add two blocking tasks. 218 // Add two blocking tasks.
217 pool_->PostTask(CreateNewBlockingIncrementingTask()); 219 pool_->PostTask(FROM_HERE, CreateNewBlockingIncrementingTask());
218 pool_->PostTask(CreateNewBlockingIncrementingTask()); 220 pool_->PostTask(FROM_HERE, CreateNewBlockingIncrementingTask());
219 221
220 EXPECT_EQ(0, counter_) << "Blocking tasks should not have started yet."; 222 EXPECT_EQ(0, counter_) << "Blocking tasks should not have started yet.";
221 223
222 WaitForTasksToStart(2); 224 WaitForTasksToStart(2);
223 start_.Signal(); 225 start_.Signal();
224 WaitForIdleThreads(2); 226 WaitForIdleThreads(2);
225 227
226 EXPECT_EQ(2U, unique_threads_.size()); 228 EXPECT_EQ(2U, unique_threads_.size());
227 EXPECT_EQ(2, peer_.num_idle_threads()) << "Existing threads are now idle."; 229 EXPECT_EQ(2, peer_.num_idle_threads()) << "Existing threads are now idle.";
228 EXPECT_EQ(2, counter_); 230 EXPECT_EQ(2, counter_);
229 } 231 }
230 232
231 TEST_F(PosixDynamicThreadPoolTest, Complex) { 233 TEST_F(PosixDynamicThreadPoolTest, Complex) {
232 // Add two non blocking tasks and wait for them to finish. 234 // Add two non blocking tasks and wait for them to finish.
233 pool_->PostTask(CreateNewIncrementingTask()); 235 pool_->PostTask(FROM_HERE, CreateNewIncrementingTask());
234 236
235 WaitForIdleThreads(1); 237 WaitForIdleThreads(1);
236 238
237 // Add two blocking tasks, start them simultaneously, and wait for them to 239 // Add two blocking tasks, start them simultaneously, and wait for them to
238 // finish. 240 // finish.
239 pool_->PostTask(CreateNewBlockingIncrementingTask()); 241 pool_->PostTask(FROM_HERE, CreateNewBlockingIncrementingTask());
240 pool_->PostTask(CreateNewBlockingIncrementingTask()); 242 pool_->PostTask(FROM_HERE, CreateNewBlockingIncrementingTask());
241 243
242 WaitForTasksToStart(2); 244 WaitForTasksToStart(2);
243 start_.Signal(); 245 start_.Signal();
244 WaitForIdleThreads(2); 246 WaitForIdleThreads(2);
245 247
246 EXPECT_EQ(3, counter_); 248 EXPECT_EQ(3, counter_);
247 EXPECT_EQ(2, peer_.num_idle_threads()); 249 EXPECT_EQ(2, peer_.num_idle_threads());
248 EXPECT_EQ(2U, unique_threads_.size()); 250 EXPECT_EQ(2U, unique_threads_.size());
249 251
250 // Wake up all idle threads so they can exit. 252 // Wake up all idle threads so they can exit.
251 { 253 {
252 base::AutoLock locked(*peer_.lock()); 254 base::AutoLock locked(*peer_.lock());
253 while (peer_.num_idle_threads() > 0) { 255 while (peer_.num_idle_threads() > 0) {
254 peer_.tasks_available_cv()->Signal(); 256 peer_.pending_tasks_available_cv()->Signal();
255 peer_.num_idle_threads_cv()->Wait(); 257 peer_.num_idle_threads_cv()->Wait();
256 } 258 }
257 } 259 }
258 260
259 // Add another non blocking task. There are no threads to reuse. 261 // Add another non blocking task. There are no threads to reuse.
260 pool_->PostTask(CreateNewIncrementingTask()); 262 pool_->PostTask(FROM_HERE, CreateNewIncrementingTask());
261 WaitForIdleThreads(1); 263 WaitForIdleThreads(1);
262 264
263 EXPECT_EQ(3U, unique_threads_.size()); 265 EXPECT_EQ(3U, unique_threads_.size());
264 EXPECT_EQ(1, peer_.num_idle_threads()); 266 EXPECT_EQ(1, peer_.num_idle_threads());
265 EXPECT_EQ(4, counter_); 267 EXPECT_EQ(4, counter_);
266 } 268 }
267 269
268 } // namespace base 270 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698