| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 const int kIdleSecondsBeforeExit = 10 * 60; | 24 const int kIdleSecondsBeforeExit = 10 * 60; |
| 25 // A stack size of 64 KB is too small for the CERT_PKIXVerifyCert | 25 // A stack size of 64 KB is too small for the CERT_PKIXVerifyCert |
| 26 // function of NSS because of NSS bug 439169. | 26 // function of NSS because of NSS bug 439169. |
| 27 const int kWorkerThreadStackSize = 128 * 1024; | 27 const int kWorkerThreadStackSize = 128 * 1024; |
| 28 | 28 |
| 29 class WorkerPoolImpl { | 29 class WorkerPoolImpl { |
| 30 public: | 30 public: |
| 31 WorkerPoolImpl(); | 31 WorkerPoolImpl(); |
| 32 ~WorkerPoolImpl(); | 32 ~WorkerPoolImpl(); |
| 33 | 33 |
| 34 void PostTask(const tracked_objects::Location& from_here, Task* task, | |
| 35 bool task_is_slow); | |
| 36 void PostTask(const tracked_objects::Location& from_here, | 34 void PostTask(const tracked_objects::Location& from_here, |
| 37 const base::Closure& task, bool task_is_slow); | 35 const base::Closure& task, bool task_is_slow); |
| 38 | 36 |
| 39 private: | 37 private: |
| 40 scoped_refptr<base::PosixDynamicThreadPool> pool_; | 38 scoped_refptr<base::PosixDynamicThreadPool> pool_; |
| 41 }; | 39 }; |
| 42 | 40 |
| 43 WorkerPoolImpl::WorkerPoolImpl() | 41 WorkerPoolImpl::WorkerPoolImpl() |
| 44 : pool_(new base::PosixDynamicThreadPool("WorkerPool", | 42 : pool_(new base::PosixDynamicThreadPool("WorkerPool", |
| 45 kIdleSecondsBeforeExit)) { | 43 kIdleSecondsBeforeExit)) { |
| 46 } | 44 } |
| 47 | 45 |
| 48 WorkerPoolImpl::~WorkerPoolImpl() { | 46 WorkerPoolImpl::~WorkerPoolImpl() { |
| 49 pool_->Terminate(); | 47 pool_->Terminate(); |
| 50 } | 48 } |
| 51 | 49 |
| 52 void WorkerPoolImpl::PostTask(const tracked_objects::Location& from_here, | 50 void WorkerPoolImpl::PostTask(const tracked_objects::Location& from_here, |
| 53 Task* task, bool task_is_slow) { | |
| 54 pool_->PostTask(from_here, task); | |
| 55 } | |
| 56 | |
| 57 void WorkerPoolImpl::PostTask(const tracked_objects::Location& from_here, | |
| 58 const base::Closure& task, bool task_is_slow) { | 51 const base::Closure& task, bool task_is_slow) { |
| 59 pool_->PostTask(from_here, task); | 52 pool_->PostTask(from_here, task); |
| 60 } | 53 } |
| 61 | 54 |
| 62 base::LazyInstance<WorkerPoolImpl> g_lazy_worker_pool = | 55 base::LazyInstance<WorkerPoolImpl> g_lazy_worker_pool = |
| 63 LAZY_INSTANCE_INITIALIZER; | 56 LAZY_INSTANCE_INITIALIZER; |
| 64 | 57 |
| 65 class WorkerThread : public PlatformThread::Delegate { | 58 class WorkerThread : public PlatformThread::Delegate { |
| 66 public: | 59 public: |
| 67 WorkerThread(const std::string& name_prefix, | 60 WorkerThread(const std::string& name_prefix, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 start_time, tracked_objects::ThreadData::NowForEndOfRun()); | 95 start_time, tracked_objects::ThreadData::NowForEndOfRun()); |
| 103 } | 96 } |
| 104 | 97 |
| 105 // The WorkerThread is non-joinable, so it deletes itself. | 98 // The WorkerThread is non-joinable, so it deletes itself. |
| 106 delete this; | 99 delete this; |
| 107 } | 100 } |
| 108 | 101 |
| 109 } // namespace | 102 } // namespace |
| 110 | 103 |
| 111 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, | 104 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, |
| 112 Task* task, bool task_is_slow) { | |
| 113 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); | |
| 114 return true; | |
| 115 } | |
| 116 | |
| 117 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, | |
| 118 const base::Closure& task, bool task_is_slow) { | 105 const base::Closure& task, bool task_is_slow) { |
| 119 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); | 106 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); |
| 120 return true; | 107 return true; |
| 121 } | 108 } |
| 122 | 109 |
| 123 PosixDynamicThreadPool::PosixDynamicThreadPool( | 110 PosixDynamicThreadPool::PosixDynamicThreadPool( |
| 124 const std::string& name_prefix, | 111 const std::string& name_prefix, |
| 125 int idle_seconds_before_exit) | 112 int idle_seconds_before_exit) |
| 126 : name_prefix_(name_prefix), | 113 : name_prefix_(name_prefix), |
| 127 idle_seconds_before_exit_(idle_seconds_before_exit), | 114 idle_seconds_before_exit_(idle_seconds_before_exit), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 139 { | 126 { |
| 140 AutoLock locked(lock_); | 127 AutoLock locked(lock_); |
| 141 DCHECK(!terminated_) << "Thread pool is already terminated."; | 128 DCHECK(!terminated_) << "Thread pool is already terminated."; |
| 142 terminated_ = true; | 129 terminated_ = true; |
| 143 } | 130 } |
| 144 pending_tasks_available_cv_.Broadcast(); | 131 pending_tasks_available_cv_.Broadcast(); |
| 145 } | 132 } |
| 146 | 133 |
| 147 void PosixDynamicThreadPool::PostTask( | 134 void PosixDynamicThreadPool::PostTask( |
| 148 const tracked_objects::Location& from_here, | 135 const tracked_objects::Location& from_here, |
| 149 Task* task) { | |
| 150 PendingTask pending_task(from_here, | |
| 151 base::Bind(&subtle::TaskClosureAdapter::Run, | |
| 152 new subtle::TaskClosureAdapter(task))); | |
| 153 // |pending_task| and AddTask() work in conjunction here to ensure that after | |
| 154 // a successful AddTask(), the TaskClosureAdapter object is deleted on the | |
| 155 // worker thread. In AddTask(), the reference |pending_task.task| is handed | |
| 156 // off in a destructive manner to ensure that the local copy of | |
| 157 // |pending_task| doesn't keep a ref on the Closure causing the | |
| 158 // TaskClosureAdapter to be deleted on the wrong thread. | |
| 159 AddTask(&pending_task); | |
| 160 } | |
| 161 | |
| 162 void PosixDynamicThreadPool::PostTask( | |
| 163 const tracked_objects::Location& from_here, | |
| 164 const base::Closure& task) { | 136 const base::Closure& task) { |
| 165 PendingTask pending_task(from_here, task); | 137 PendingTask pending_task(from_here, task); |
| 166 AddTask(&pending_task); | 138 AddTask(&pending_task); |
| 167 } | 139 } |
| 168 | 140 |
| 169 void PosixDynamicThreadPool::AddTask(PendingTask* pending_task) { | 141 void PosixDynamicThreadPool::AddTask(PendingTask* pending_task) { |
| 170 AutoLock locked(lock_); | 142 AutoLock locked(lock_); |
| 171 DCHECK(!terminated_) << | 143 DCHECK(!terminated_) << |
| 172 "This thread pool is already terminated. Do not post new tasks."; | 144 "This thread pool is already terminated. Do not post new tasks."; |
| 173 | 145 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 return PendingTask(FROM_HERE, base::Closure()); | 179 return PendingTask(FROM_HERE, base::Closure()); |
| 208 } | 180 } |
| 209 } | 181 } |
| 210 | 182 |
| 211 PendingTask pending_task = pending_tasks_.front(); | 183 PendingTask pending_task = pending_tasks_.front(); |
| 212 pending_tasks_.pop(); | 184 pending_tasks_.pop(); |
| 213 return pending_task; | 185 return pending_task; |
| 214 } | 186 } |
| 215 | 187 |
| 216 } // namespace base | 188 } // namespace base |
| OLD | NEW |