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