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 |