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/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
14 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
| 15 #include "base/threading/thread_local.h" |
15 #include "base/threading/worker_pool.h" | 16 #include "base/threading/worker_pool.h" |
16 #include "base/tracked_objects.h" | 17 #include "base/tracked_objects.h" |
17 | 18 |
18 using tracked_objects::TrackedTime; | 19 using tracked_objects::TrackedTime; |
19 | 20 |
20 namespace base { | 21 namespace base { |
21 | 22 |
22 namespace { | 23 namespace { |
23 | 24 |
| 25 base::LazyInstance<ThreadLocalBoolean>::Leaky |
| 26 g_worker_pool_running_on_this_thread = LAZY_INSTANCE_INITIALIZER; |
| 27 |
24 const int kIdleSecondsBeforeExit = 10 * 60; | 28 const int kIdleSecondsBeforeExit = 10 * 60; |
25 // A stack size of 64 KB is too small for the CERT_PKIXVerifyCert | 29 // A stack size of 64 KB is too small for the CERT_PKIXVerifyCert |
26 // function of NSS because of NSS bug 439169. | 30 // function of NSS because of NSS bug 439169. |
27 const int kWorkerThreadStackSize = 128 * 1024; | 31 const int kWorkerThreadStackSize = 128 * 1024; |
28 | 32 |
29 class WorkerPoolImpl { | 33 class WorkerPoolImpl { |
30 public: | 34 public: |
31 WorkerPoolImpl(); | 35 WorkerPoolImpl(); |
32 ~WorkerPoolImpl(); | 36 ~WorkerPoolImpl(); |
33 | 37 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 virtual void ThreadMain() OVERRIDE; | 69 virtual void ThreadMain() OVERRIDE; |
66 | 70 |
67 private: | 71 private: |
68 const std::string name_prefix_; | 72 const std::string name_prefix_; |
69 scoped_refptr<base::PosixDynamicThreadPool> pool_; | 73 scoped_refptr<base::PosixDynamicThreadPool> pool_; |
70 | 74 |
71 DISALLOW_COPY_AND_ASSIGN(WorkerThread); | 75 DISALLOW_COPY_AND_ASSIGN(WorkerThread); |
72 }; | 76 }; |
73 | 77 |
74 void WorkerThread::ThreadMain() { | 78 void WorkerThread::ThreadMain() { |
| 79 g_worker_pool_running_on_this_thread.Get().Set(true); |
75 const std::string name = base::StringPrintf( | 80 const std::string name = base::StringPrintf( |
76 "%s/%d", name_prefix_.c_str(), PlatformThread::CurrentId()); | 81 "%s/%d", name_prefix_.c_str(), PlatformThread::CurrentId()); |
77 // Note |name.c_str()| must remain valid for for the whole life of the thread. | 82 // Note |name.c_str()| must remain valid for for the whole life of the thread. |
78 PlatformThread::SetName(name.c_str()); | 83 PlatformThread::SetName(name.c_str()); |
79 | 84 |
80 for (;;) { | 85 for (;;) { |
81 PendingTask pending_task = pool_->WaitForTask(); | 86 PendingTask pending_task = pool_->WaitForTask(); |
82 if (pending_task.task.is_null()) | 87 if (pending_task.task.is_null()) |
83 break; | 88 break; |
84 TRACE_EVENT2("task", "WorkerThread::ThreadMain::Run", | 89 TRACE_EVENT2("task", "WorkerThread::ThreadMain::Run", |
85 "src_file", pending_task.posted_from.file_name(), | 90 "src_file", pending_task.posted_from.file_name(), |
86 "src_func", pending_task.posted_from.function_name()); | 91 "src_func", pending_task.posted_from.function_name()); |
87 | 92 |
88 TrackedTime start_time = | 93 TrackedTime start_time = |
89 tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally); | 94 tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally); |
90 | 95 |
91 pending_task.task.Run(); | 96 pending_task.task.Run(); |
92 | 97 |
93 tracked_objects::ThreadData::TallyRunOnWorkerThreadIfTracking( | 98 tracked_objects::ThreadData::TallyRunOnWorkerThreadIfTracking( |
94 pending_task.birth_tally, TrackedTime(pending_task.time_posted), | 99 pending_task.birth_tally, TrackedTime(pending_task.time_posted), |
95 start_time, tracked_objects::ThreadData::NowForEndOfRun()); | 100 start_time, tracked_objects::ThreadData::NowForEndOfRun()); |
96 } | 101 } |
97 | 102 |
98 // The WorkerThread is non-joinable, so it deletes itself. | 103 // The WorkerThread is non-joinable, so it deletes itself. |
99 delete this; | 104 delete this; |
100 } | 105 } |
101 | 106 |
102 } // namespace | 107 } // namespace |
103 | 108 |
| 109 // static |
104 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, | 110 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, |
105 const base::Closure& task, bool task_is_slow) { | 111 const base::Closure& task, bool task_is_slow) { |
106 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); | 112 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); |
107 return true; | 113 return true; |
108 } | 114 } |
109 | 115 |
| 116 // static |
| 117 bool WorkerPool::RunsTasksOnCurrentThread() { |
| 118 return g_worker_pool_running_on_this_thread.Get().Get(); |
| 119 } |
| 120 |
110 PosixDynamicThreadPool::PosixDynamicThreadPool( | 121 PosixDynamicThreadPool::PosixDynamicThreadPool( |
111 const std::string& name_prefix, | 122 const std::string& name_prefix, |
112 int idle_seconds_before_exit) | 123 int idle_seconds_before_exit) |
113 : name_prefix_(name_prefix), | 124 : name_prefix_(name_prefix), |
114 idle_seconds_before_exit_(idle_seconds_before_exit), | 125 idle_seconds_before_exit_(idle_seconds_before_exit), |
115 pending_tasks_available_cv_(&lock_), | 126 pending_tasks_available_cv_(&lock_), |
116 num_idle_threads_(0), | 127 num_idle_threads_(0), |
117 terminated_(false), | 128 terminated_(false), |
118 num_idle_threads_cv_(NULL) {} | 129 num_idle_threads_cv_(NULL) {} |
119 | 130 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 return PendingTask(FROM_HERE, base::Closure()); | 190 return PendingTask(FROM_HERE, base::Closure()); |
180 } | 191 } |
181 } | 192 } |
182 | 193 |
183 PendingTask pending_task = pending_tasks_.front(); | 194 PendingTask pending_task = pending_tasks_.front(); |
184 pending_tasks_.pop(); | 195 pending_tasks_.pop(); |
185 return pending_task; | 196 return pending_task; |
186 } | 197 } |
187 | 198 |
188 } // namespace base | 199 } // namespace base |
OLD | NEW |