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

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

Issue 8565024: base: Refactor PendingTask out of MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review fixes. Created 9 years, 1 month 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
« no previous file with comments | « base/threading/worker_pool_posix.h ('k') | base/threading/worker_pool_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/stringprintf.h" 12 #include "base/stringprintf.h"
13 #include "base/task.h" 13 #include "base/task.h"
14 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
15 #include "base/threading/worker_pool.h" 15 #include "base/threading/worker_pool.h"
16 #include "base/tracked_objects.h" 16 #include "base/tracked_objects.h"
17 17
18 using tracked_objects::TrackedTime;
19
18 namespace base { 20 namespace base {
19 21
20 namespace { 22 namespace {
21 23
22 const int kIdleSecondsBeforeExit = 10 * 60; 24 const int kIdleSecondsBeforeExit = 10 * 60;
23 // 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
24 // function of NSS because of NSS bug 439169. 26 // function of NSS because of NSS bug 439169.
25 const int kWorkerThreadStackSize = 128 * 1024; 27 const int kWorkerThreadStackSize = 128 * 1024;
26 28
27 class WorkerPoolImpl { 29 class WorkerPoolImpl {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 DISALLOW_COPY_AND_ASSIGN(WorkerThread); 78 DISALLOW_COPY_AND_ASSIGN(WorkerThread);
77 }; 79 };
78 80
79 void WorkerThread::ThreadMain() { 81 void WorkerThread::ThreadMain() {
80 const std::string name = base::StringPrintf( 82 const std::string name = base::StringPrintf(
81 "%s/%d", name_prefix_.c_str(), PlatformThread::CurrentId()); 83 "%s/%d", name_prefix_.c_str(), PlatformThread::CurrentId());
82 // Note |name.c_str()| must remain valid for for the whole life of the thread. 84 // Note |name.c_str()| must remain valid for for the whole life of the thread.
83 PlatformThread::SetName(name.c_str()); 85 PlatformThread::SetName(name.c_str());
84 86
85 for (;;) { 87 for (;;) {
86 PosixDynamicThreadPool::PendingTask pending_task = pool_->WaitForTask(); 88 PendingTask pending_task = pool_->WaitForTask();
87 if (pending_task.task.is_null()) 89 if (pending_task.task.is_null())
88 break; 90 break;
89 UNSHIPPED_TRACE_EVENT2("task", "WorkerThread::ThreadMain::Run", 91 UNSHIPPED_TRACE_EVENT2("task", "WorkerThread::ThreadMain::Run",
90 "src_file", pending_task.posted_from.file_name(), 92 "src_file", pending_task.posted_from.file_name(),
91 "src_func", pending_task.posted_from.function_name()); 93 "src_func", pending_task.posted_from.function_name());
92 94
93 tracked_objects::TrackedTime start_time = 95 TrackedTime start_time =
94 tracked_objects::ThreadData::NowForStartOfRun(); 96 tracked_objects::ThreadData::NowForStartOfRun();
95 97
96 pending_task.task.Run(); 98 pending_task.task.Run();
97 99
98 tracked_objects::ThreadData::TallyRunOnWorkerThreadIfTracking( 100 tracked_objects::ThreadData::TallyRunOnWorkerThreadIfTracking(
99 pending_task.birth_tally, pending_task.time_posted, 101 pending_task.birth_tally, TrackedTime(pending_task.time_posted),
100 start_time, tracked_objects::ThreadData::NowForEndOfRun()); 102 start_time, tracked_objects::ThreadData::NowForEndOfRun());
101 } 103 }
102 104
103 // The WorkerThread is non-joinable, so it deletes itself. 105 // The WorkerThread is non-joinable, so it deletes itself.
104 delete this; 106 delete this;
105 } 107 }
106 108
107 } // namespace 109 } // namespace
108 110
109 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, 111 bool WorkerPool::PostTask(const tracked_objects::Location& from_here,
110 Task* task, bool task_is_slow) { 112 Task* task, bool task_is_slow) {
111 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); 113 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow);
112 return true; 114 return true;
113 } 115 }
114 116
115 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, 117 bool WorkerPool::PostTask(const tracked_objects::Location& from_here,
116 const base::Closure& task, bool task_is_slow) { 118 const base::Closure& task, bool task_is_slow) {
117 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); 119 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow);
118 return true; 120 return true;
119 } 121 }
120 122
121 PosixDynamicThreadPool::PendingTask::PendingTask(
122 const tracked_objects::Location& posted_from,
123 const base::Closure& task)
124 : posted_from(posted_from),
125 task(task) {
126 birth_tally = tracked_objects::ThreadData::TallyABirthIfActive(posted_from);
127 time_posted = tracked_objects::ThreadData::Now();
128 }
129
130 PosixDynamicThreadPool::PendingTask::~PendingTask() {
131 }
132
133 PosixDynamicThreadPool::PosixDynamicThreadPool( 123 PosixDynamicThreadPool::PosixDynamicThreadPool(
134 const std::string& name_prefix, 124 const std::string& name_prefix,
135 int idle_seconds_before_exit) 125 int idle_seconds_before_exit)
136 : name_prefix_(name_prefix), 126 : name_prefix_(name_prefix),
137 idle_seconds_before_exit_(idle_seconds_before_exit), 127 idle_seconds_before_exit_(idle_seconds_before_exit),
138 pending_tasks_available_cv_(&lock_), 128 pending_tasks_available_cv_(&lock_),
139 num_idle_threads_(0), 129 num_idle_threads_(0),
140 terminated_(false), 130 terminated_(false),
141 num_idle_threads_cv_(NULL) {} 131 num_idle_threads_cv_(NULL) {}
142 132
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 pending_tasks_available_cv_.Signal(); 181 pending_tasks_available_cv_.Signal();
192 } else { 182 } else {
193 // The new PlatformThread will take ownership of the WorkerThread object, 183 // The new PlatformThread will take ownership of the WorkerThread object,
194 // which will delete itself on exit. 184 // which will delete itself on exit.
195 WorkerThread* worker = 185 WorkerThread* worker =
196 new WorkerThread(name_prefix_, this); 186 new WorkerThread(name_prefix_, this);
197 PlatformThread::CreateNonJoinable(kWorkerThreadStackSize, worker); 187 PlatformThread::CreateNonJoinable(kWorkerThreadStackSize, worker);
198 } 188 }
199 } 189 }
200 190
201 PosixDynamicThreadPool::PendingTask PosixDynamicThreadPool::WaitForTask() { 191 PendingTask PosixDynamicThreadPool::WaitForTask() {
202 AutoLock locked(lock_); 192 AutoLock locked(lock_);
203 193
204 if (terminated_) 194 if (terminated_)
205 return PendingTask(FROM_HERE, base::Closure()); 195 return PendingTask(FROM_HERE, base::Closure());
206 196
207 if (pending_tasks_.empty()) { // No work available, wait for work. 197 if (pending_tasks_.empty()) { // No work available, wait for work.
208 num_idle_threads_++; 198 num_idle_threads_++;
209 if (num_idle_threads_cv_.get()) 199 if (num_idle_threads_cv_.get())
210 num_idle_threads_cv_->Signal(); 200 num_idle_threads_cv_->Signal();
211 pending_tasks_available_cv_.TimedWait( 201 pending_tasks_available_cv_.TimedWait(
212 TimeDelta::FromSeconds(idle_seconds_before_exit_)); 202 TimeDelta::FromSeconds(idle_seconds_before_exit_));
213 num_idle_threads_--; 203 num_idle_threads_--;
214 if (num_idle_threads_cv_.get()) 204 if (num_idle_threads_cv_.get())
215 num_idle_threads_cv_->Signal(); 205 num_idle_threads_cv_->Signal();
216 if (pending_tasks_.empty()) { 206 if (pending_tasks_.empty()) {
217 // We waited for work, but there's still no work. Return NULL to signal 207 // We waited for work, but there's still no work. Return NULL to signal
218 // the thread to terminate. 208 // the thread to terminate.
219 return PendingTask(FROM_HERE, base::Closure()); 209 return PendingTask(FROM_HERE, base::Closure());
220 } 210 }
221 } 211 }
222 212
223 PendingTask pending_task = pending_tasks_.front(); 213 PendingTask pending_task = pending_tasks_.front();
224 pending_tasks_.pop(); 214 pending_tasks_.pop();
225 return pending_task; 215 return pending_task;
226 } 216 }
227 217
228 } // namespace base 218 } // namespace base
OLDNEW
« no previous file with comments | « base/threading/worker_pool_posix.h ('k') | base/threading/worker_pool_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698