Chromium Code Reviews| 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/worker_pool_posix.h" | 5 #include "base/threading/worker_pool_posix.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 AutoLock locked(lock_); | 133 AutoLock locked(lock_); |
| 134 DCHECK(!terminated_) << "Thread pool is already terminated."; | 134 DCHECK(!terminated_) << "Thread pool is already terminated."; |
| 135 terminated_ = true; | 135 terminated_ = true; |
| 136 } | 136 } |
| 137 pending_tasks_available_cv_.Broadcast(); | 137 pending_tasks_available_cv_.Broadcast(); |
| 138 } | 138 } |
| 139 | 139 |
| 140 void PosixDynamicThreadPool::PostTask( | 140 void PosixDynamicThreadPool::PostTask( |
| 141 const tracked_objects::Location& from_here, | 141 const tracked_objects::Location& from_here, |
| 142 const base::Closure& task) { | 142 const base::Closure& task) { |
| 143 PendingTask pending_task(from_here, task); | 143 PendingTask pending_task(from_here, |
| 144 MessageLoop::current()->current_pending_task_, | |
|
danakj
2015/04/03 17:18:35
The use of MessageLoop::current()->current_pending
| |
| 145 task); | |
| 144 AddTask(&pending_task); | 146 AddTask(&pending_task); |
| 145 } | 147 } |
| 146 | 148 |
| 147 void PosixDynamicThreadPool::AddTask(PendingTask* pending_task) { | 149 void PosixDynamicThreadPool::AddTask(PendingTask* pending_task) { |
| 148 AutoLock locked(lock_); | 150 AutoLock locked(lock_); |
| 149 DCHECK(!terminated_) << | 151 DCHECK(!terminated_) << |
| 150 "This thread pool is already terminated. Do not post new tasks."; | 152 "This thread pool is already terminated. Do not post new tasks."; |
| 151 | 153 |
| 152 pending_tasks_.push(*pending_task); | 154 pending_tasks_.push(*pending_task); |
| 153 pending_task->task.Reset(); | 155 pending_task->task.Reset(); |
| 154 | 156 |
| 155 // We have enough worker threads. | 157 // We have enough worker threads. |
| 156 if (static_cast<size_t>(num_idle_threads_) >= pending_tasks_.size()) { | 158 if (static_cast<size_t>(num_idle_threads_) >= pending_tasks_.size()) { |
| 157 pending_tasks_available_cv_.Signal(); | 159 pending_tasks_available_cv_.Signal(); |
| 158 } else { | 160 } else { |
| 159 // The new PlatformThread will take ownership of the WorkerThread object, | 161 // The new PlatformThread will take ownership of the WorkerThread object, |
| 160 // which will delete itself on exit. | 162 // which will delete itself on exit. |
| 161 WorkerThread* worker = | 163 WorkerThread* worker = |
| 162 new WorkerThread(name_prefix_, this); | 164 new WorkerThread(name_prefix_, this); |
| 163 PlatformThread::CreateNonJoinable(0, worker); | 165 PlatformThread::CreateNonJoinable(0, worker); |
| 164 } | 166 } |
| 165 } | 167 } |
| 166 | 168 |
| 167 PendingTask PosixDynamicThreadPool::WaitForTask() { | 169 PendingTask PosixDynamicThreadPool::WaitForTask() { |
| 168 AutoLock locked(lock_); | 170 AutoLock locked(lock_); |
| 169 | 171 |
| 170 if (terminated_) | 172 if (terminated_) |
| 171 return PendingTask(FROM_HERE, base::Closure()); | 173 return PendingTask(FROM_HERE, NULL, base::Closure()); |
| 172 | 174 |
| 173 if (pending_tasks_.empty()) { // No work available, wait for work. | 175 if (pending_tasks_.empty()) { // No work available, wait for work. |
| 174 num_idle_threads_++; | 176 num_idle_threads_++; |
| 175 if (num_idle_threads_cv_.get()) | 177 if (num_idle_threads_cv_.get()) |
| 176 num_idle_threads_cv_->Signal(); | 178 num_idle_threads_cv_->Signal(); |
| 177 pending_tasks_available_cv_.TimedWait( | 179 pending_tasks_available_cv_.TimedWait( |
| 178 TimeDelta::FromSeconds(idle_seconds_before_exit_)); | 180 TimeDelta::FromSeconds(idle_seconds_before_exit_)); |
| 179 num_idle_threads_--; | 181 num_idle_threads_--; |
| 180 if (num_idle_threads_cv_.get()) | 182 if (num_idle_threads_cv_.get()) |
| 181 num_idle_threads_cv_->Signal(); | 183 num_idle_threads_cv_->Signal(); |
| 182 if (pending_tasks_.empty()) { | 184 if (pending_tasks_.empty()) { |
| 183 // We waited for work, but there's still no work. Return NULL to signal | 185 // We waited for work, but there's still no work. Return NULL to signal |
| 184 // the thread to terminate. | 186 // the thread to terminate. |
| 185 return PendingTask(FROM_HERE, base::Closure()); | 187 return PendingTask(FROM_HERE, NULL, base::Closure()); |
| 186 } | 188 } |
| 187 } | 189 } |
| 188 | 190 |
| 189 PendingTask pending_task = pending_tasks_.front(); | 191 PendingTask pending_task = pending_tasks_.front(); |
| 190 pending_tasks_.pop(); | 192 pending_tasks_.pop(); |
| 191 return pending_task; | 193 return pending_task; |
| 192 } | 194 } |
| 193 | 195 |
| 194 } // namespace base | 196 } // namespace base |
| OLD | NEW |