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/sequenced_worker_pool.h" | 5 #include "base/threading/sequenced_worker_pool.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 return true; | 110 return true; |
111 | 111 |
112 if (lhs.time_to_run > rhs.time_to_run) | 112 if (lhs.time_to_run > rhs.time_to_run) |
113 return false; | 113 return false; |
114 | 114 |
115 // If the time happen to match, then we use the sequence number to decide. | 115 // If the time happen to match, then we use the sequence number to decide. |
116 return lhs.sequence_task_number < rhs.sequence_task_number; | 116 return lhs.sequence_task_number < rhs.sequence_task_number; |
117 } | 117 } |
118 }; | 118 }; |
119 | 119 |
120 // Create a process-wide unique ID to represent this task in trace events. This | |
121 // will be mangled with a Process ID hash to reduce the likelyhood of colliding | |
122 // with MessageLoop pointers on other processes. | |
123 uint64_t GetTaskTraceID(const SequencedTask& task, void* pool) { | |
124 return (static_cast<uint64_t>(task.trace_id) << 32) | | |
125 static_cast<uint64_t>(reinterpret_cast<intptr_t>(pool)); | |
126 } | |
127 | |
120 // SequencedWorkerPoolTaskRunner --------------------------------------------- | 128 // SequencedWorkerPoolTaskRunner --------------------------------------------- |
121 // A TaskRunner which posts tasks to a SequencedWorkerPool with a | 129 // A TaskRunner which posts tasks to a SequencedWorkerPool with a |
122 // fixed ShutdownBehavior. | 130 // fixed ShutdownBehavior. |
123 // | 131 // |
124 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). | 132 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
125 class SequencedWorkerPoolTaskRunner : public TaskRunner { | 133 class SequencedWorkerPoolTaskRunner : public TaskRunner { |
126 public: | 134 public: |
127 SequencedWorkerPoolTaskRunner( | 135 SequencedWorkerPoolTaskRunner( |
128 scoped_refptr<SequencedWorkerPool> pool, | 136 scoped_refptr<SequencedWorkerPool> pool, |
129 SequencedWorkerPool::WorkerShutdown shutdown_behavior); | 137 SequencedWorkerPool::WorkerShutdown shutdown_behavior); |
(...skipping 30 matching lines...) Expand all Loading... | |
160 return pool_->PostWorkerTaskWithShutdownBehavior( | 168 return pool_->PostWorkerTaskWithShutdownBehavior( |
161 from_here, task, shutdown_behavior_); | 169 from_here, task, shutdown_behavior_); |
162 } | 170 } |
163 return pool_->PostDelayedWorkerTask(from_here, task, delay); | 171 return pool_->PostDelayedWorkerTask(from_here, task, delay); |
164 } | 172 } |
165 | 173 |
166 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { | 174 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { |
167 return pool_->RunsTasksOnCurrentThread(); | 175 return pool_->RunsTasksOnCurrentThread(); |
168 } | 176 } |
169 | 177 |
170 // SequencedWorkerPoolSequencedTaskRunner ------------------------------------ | 178 } // namespace |
179 | |
180 // SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner --------------- | |
robliao
2016/09/15 14:14:16
Make SequencedWorkerPool::SequencedTaskRunner or S
fdoray
2016/09/15 15:21:59
Done. (PoolSequencedTaskRunner instead of PoolTask
| |
171 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a | 181 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a |
172 // fixed sequence token. | 182 // fixed sequence token. |
173 // | 183 // |
174 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). | 184 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
175 class SequencedWorkerPoolSequencedTaskRunner : public SequencedTaskRunner { | 185 class SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner |
186 : public SequencedTaskRunner { | |
176 public: | 187 public: |
177 SequencedWorkerPoolSequencedTaskRunner( | 188 SequencedWorkerPoolSequencedTaskRunner( |
178 scoped_refptr<SequencedWorkerPool> pool, | 189 scoped_refptr<SequencedWorkerPool> pool, |
179 SequencedWorkerPool::SequenceToken token, | 190 SequencedWorkerPool::SequenceToken token, |
180 SequencedWorkerPool::WorkerShutdown shutdown_behavior); | 191 SequencedWorkerPool::WorkerShutdown shutdown_behavior); |
181 | 192 |
182 // TaskRunner implementation | 193 // TaskRunner implementation |
183 bool PostDelayedTask(const tracked_objects::Location& from_here, | 194 bool PostDelayedTask(const tracked_objects::Location& from_here, |
184 const Closure& task, | 195 const Closure& task, |
185 TimeDelta delay) override; | 196 TimeDelta delay) override; |
186 bool RunsTasksOnCurrentThread() const override; | 197 bool RunsTasksOnCurrentThread() const override; |
187 | 198 |
188 // SequencedTaskRunner implementation | 199 // SequencedTaskRunner implementation |
189 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 200 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
190 const Closure& task, | 201 const Closure& task, |
191 TimeDelta delay) override; | 202 TimeDelta delay) override; |
192 | 203 |
193 private: | 204 private: |
194 ~SequencedWorkerPoolSequencedTaskRunner() override; | 205 ~SequencedWorkerPoolSequencedTaskRunner() override; |
195 | 206 |
196 const scoped_refptr<SequencedWorkerPool> pool_; | 207 const scoped_refptr<SequencedWorkerPool> pool_; |
197 | 208 |
198 const SequencedWorkerPool::SequenceToken token_; | 209 const SequencedWorkerPool::SequenceToken token_; |
199 | 210 |
200 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; | 211 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; |
201 | 212 |
202 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolSequencedTaskRunner); | 213 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolSequencedTaskRunner); |
203 }; | 214 }; |
204 | 215 |
205 SequencedWorkerPoolSequencedTaskRunner::SequencedWorkerPoolSequencedTaskRunner( | 216 SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner:: |
206 scoped_refptr<SequencedWorkerPool> pool, | 217 SequencedWorkerPoolSequencedTaskRunner( |
207 SequencedWorkerPool::SequenceToken token, | 218 scoped_refptr<SequencedWorkerPool> pool, |
208 SequencedWorkerPool::WorkerShutdown shutdown_behavior) | 219 SequencedWorkerPool::SequenceToken token, |
220 SequencedWorkerPool::WorkerShutdown shutdown_behavior) | |
209 : pool_(std::move(pool)), | 221 : pool_(std::move(pool)), |
210 token_(token), | 222 token_(token), |
211 shutdown_behavior_(shutdown_behavior) {} | 223 shutdown_behavior_(shutdown_behavior) {} |
212 | 224 |
213 SequencedWorkerPoolSequencedTaskRunner:: | 225 SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner:: |
214 ~SequencedWorkerPoolSequencedTaskRunner() { | 226 ~SequencedWorkerPoolSequencedTaskRunner() = default; |
215 } | |
216 | 227 |
217 bool SequencedWorkerPoolSequencedTaskRunner::PostDelayedTask( | 228 bool SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner:: |
218 const tracked_objects::Location& from_here, | 229 PostDelayedTask(const tracked_objects::Location& from_here, |
219 const Closure& task, | 230 const Closure& task, |
220 TimeDelta delay) { | 231 TimeDelta delay) { |
221 if (delay.is_zero()) { | 232 if (delay.is_zero()) { |
222 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( | 233 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( |
223 token_, from_here, task, shutdown_behavior_); | 234 token_, from_here, task, shutdown_behavior_); |
224 } | 235 } |
225 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, task, delay); | 236 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, task, delay); |
226 } | 237 } |
227 | 238 |
228 bool SequencedWorkerPoolSequencedTaskRunner::RunsTasksOnCurrentThread() const { | 239 bool SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner:: |
240 RunsTasksOnCurrentThread() const { | |
229 return pool_->IsRunningSequenceOnCurrentThread(token_); | 241 return pool_->IsRunningSequenceOnCurrentThread(token_); |
230 } | 242 } |
231 | 243 |
232 bool SequencedWorkerPoolSequencedTaskRunner::PostNonNestableDelayedTask( | 244 bool SequencedWorkerPool::SequencedWorkerPoolSequencedTaskRunner:: |
233 const tracked_objects::Location& from_here, | 245 PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
234 const Closure& task, | 246 const Closure& task, |
235 TimeDelta delay) { | 247 TimeDelta delay) { |
236 // There's no way to run nested tasks, so simply forward to | 248 // There's no way to run nested tasks, so simply forward to |
237 // PostDelayedTask. | 249 // PostDelayedTask. |
238 return PostDelayedTask(from_here, task, delay); | 250 return PostDelayedTask(from_here, task, delay); |
239 } | 251 } |
240 | 252 |
241 // Create a process-wide unique ID to represent this task in trace events. This | |
242 // will be mangled with a Process ID hash to reduce the likelyhood of colliding | |
243 // with MessageLoop pointers on other processes. | |
244 uint64_t GetTaskTraceID(const SequencedTask& task, void* pool) { | |
245 return (static_cast<uint64_t>(task.trace_id) << 32) | | |
246 static_cast<uint64_t>(reinterpret_cast<intptr_t>(pool)); | |
247 } | |
248 | |
249 } // namespace | |
250 | |
251 // Worker --------------------------------------------------------------------- | 253 // Worker --------------------------------------------------------------------- |
252 | 254 |
253 class SequencedWorkerPool::Worker : public SimpleThread { | 255 class SequencedWorkerPool::Worker : public SimpleThread { |
254 public: | 256 public: |
255 // Hold a (cyclic) ref to |worker_pool|, since we want to keep it | 257 // Hold a (cyclic) ref to |worker_pool|, since we want to keep it |
256 // around as long as we are running. | 258 // around as long as we are running. |
257 Worker(scoped_refptr<SequencedWorkerPool> worker_pool, | 259 Worker(scoped_refptr<SequencedWorkerPool> worker_pool, |
258 int thread_number, | 260 int thread_number, |
259 const std::string& thread_name_prefix); | 261 const std::string& thread_name_prefix); |
260 ~Worker() override; | 262 ~Worker() override; |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 } | 834 } |
833 return runs_tasks_on_verifier_->RunsTasksOnCurrentThread(); | 835 return runs_tasks_on_verifier_->RunsTasksOnCurrentThread(); |
834 } else { | 836 } else { |
835 return ContainsKey(threads_, PlatformThread::CurrentId()); | 837 return ContainsKey(threads_, PlatformThread::CurrentId()); |
836 } | 838 } |
837 } | 839 } |
838 | 840 |
839 bool SequencedWorkerPool::Inner::IsRunningSequenceOnCurrentThread( | 841 bool SequencedWorkerPool::Inner::IsRunningSequenceOnCurrentThread( |
840 SequenceToken sequence_token) const { | 842 SequenceToken sequence_token) const { |
841 AutoLock lock(lock_); | 843 AutoLock lock(lock_); |
842 if (subtle::NoBarrier_Load(&g_all_pools_state) == | 844 DCHECK_NE(subtle::NoBarrier_Load(&g_all_pools_state), |
gab
2016/09/15 13:50:47
Actually, under redirection: SWP::GetSequencedTask
fdoray
2016/09/15 15:21:59
You're right. This CL no longer changes IsRunningS
| |
843 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { | 845 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER); |
844 // TODO(gab): This currently only verifies that the current thread is a | 846 ThreadMap::const_iterator found = threads_.find(PlatformThread::CurrentId()); |
845 // thread on which a task bound to |sequence_token| *could* run, but it | 847 if (found == threads_.end()) |
gab
2016/09/15 13:50:47
Incorporate below, i.e.
return found != threads_.
fdoray
2016/09/15 15:21:59
I'll fix this method in a separate CL.
| |
846 // doesn't verify that the current is *currently running* a task bound to | 848 return false; |
847 // |sequence_token|. | 849 return found->second->is_processing_task() && |
848 const auto sequenced_task_runner_it = | 850 sequence_token.Equals(found->second->task_sequence_token()); |
849 sequenced_task_runner_map_.find(sequence_token.id_); | |
850 return sequenced_task_runner_it != sequenced_task_runner_map_.end() && | |
851 sequenced_task_runner_it->second->RunsTasksOnCurrentThread(); | |
852 } else { | |
853 ThreadMap::const_iterator found = | |
854 threads_.find(PlatformThread::CurrentId()); | |
855 if (found == threads_.end()) | |
856 return false; | |
857 return found->second->is_processing_task() && | |
858 sequence_token.Equals(found->second->task_sequence_token()); | |
859 } | |
860 } | 851 } |
861 | 852 |
862 // See https://code.google.com/p/chromium/issues/detail?id=168415 | 853 // See https://code.google.com/p/chromium/issues/detail?id=168415 |
863 void SequencedWorkerPool::Inner::CleanupForTesting() { | 854 void SequencedWorkerPool::Inner::CleanupForTesting() { |
864 DCHECK(!RunsTasksOnCurrentThread()); | 855 DCHECK(!RunsTasksOnCurrentThread()); |
865 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 856 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
866 AutoLock lock(lock_); | 857 AutoLock lock(lock_); |
867 CHECK_EQ(CLEANUP_DONE, cleanup_state_); | 858 CHECK_EQ(CLEANUP_DONE, cleanup_state_); |
868 if (shutdown_called_) | 859 if (shutdown_called_) |
869 return; | 860 return; |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1547 const tracked_objects::Location& from_here, | 1538 const tracked_objects::Location& from_here, |
1548 const Closure& task, | 1539 const Closure& task, |
1549 TimeDelta delay) { | 1540 TimeDelta delay) { |
1550 return PostDelayedWorkerTask(from_here, task, delay); | 1541 return PostDelayedWorkerTask(from_here, task, delay); |
1551 } | 1542 } |
1552 | 1543 |
1553 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { | 1544 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { |
1554 return inner_->RunsTasksOnCurrentThread(); | 1545 return inner_->RunsTasksOnCurrentThread(); |
1555 } | 1546 } |
1556 | 1547 |
1557 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( | |
1558 SequenceToken sequence_token) const { | |
1559 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); | |
1560 } | |
1561 | |
1562 void SequencedWorkerPool::FlushForTesting() { | 1548 void SequencedWorkerPool::FlushForTesting() { |
1563 inner_->CleanupForTesting(); | 1549 inner_->CleanupForTesting(); |
1564 } | 1550 } |
1565 | 1551 |
1566 void SequencedWorkerPool::SignalHasWorkForTesting() { | 1552 void SequencedWorkerPool::SignalHasWorkForTesting() { |
1567 inner_->SignalHasWorkForTesting(); | 1553 inner_->SignalHasWorkForTesting(); |
1568 } | 1554 } |
1569 | 1555 |
1570 void SequencedWorkerPool::Shutdown(int max_new_blocking_tasks_after_shutdown) { | 1556 void SequencedWorkerPool::Shutdown(int max_new_blocking_tasks_after_shutdown) { |
1571 DCHECK(constructor_task_runner_->BelongsToCurrentThread()); | 1557 DCHECK(constructor_task_runner_->BelongsToCurrentThread()); |
1572 inner_->Shutdown(max_new_blocking_tasks_after_shutdown); | 1558 inner_->Shutdown(max_new_blocking_tasks_after_shutdown); |
1573 } | 1559 } |
1574 | 1560 |
1575 bool SequencedWorkerPool::IsShutdownInProgress() { | 1561 bool SequencedWorkerPool::IsShutdownInProgress() { |
1576 return inner_->IsShutdownInProgress(); | 1562 return inner_->IsShutdownInProgress(); |
1577 } | 1563 } |
1578 | 1564 |
1565 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( | |
1566 SequenceToken sequence_token) const { | |
1567 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); | |
1568 } | |
1569 | |
1579 } // namespace base | 1570 } // namespace base |
OLD | NEW |