Chromium Code Reviews| 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 |