OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/task_scheduler/scheduler_thread_pool.h" | 5 #include "base/task_scheduler/scheduler_thread_pool.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 void SchedulerThreadPool::SchedulerWorkerThreadDelegateImpl::OnMainEntry() { | 231 void SchedulerThreadPool::SchedulerWorkerThreadDelegateImpl::OnMainEntry() { |
232 DCHECK(!tls_current_thread_pool.Get().Get()); | 232 DCHECK(!tls_current_thread_pool.Get().Get()); |
233 tls_current_thread_pool.Get().Set(outer_); | 233 tls_current_thread_pool.Get().Set(outer_); |
234 } | 234 } |
235 | 235 |
236 scoped_refptr<Sequence> | 236 scoped_refptr<Sequence> |
237 SchedulerThreadPool::SchedulerWorkerThreadDelegateImpl::GetWork( | 237 SchedulerThreadPool::SchedulerWorkerThreadDelegateImpl::GetWork( |
238 SchedulerWorkerThread* worker_thread) { | 238 SchedulerWorkerThread* worker_thread) { |
239 std::unique_ptr<PriorityQueue::Transaction> transaction( | 239 std::unique_ptr<PriorityQueue::Transaction> transaction( |
240 outer_->shared_priority_queue_.BeginTransaction()); | 240 outer_->shared_priority_queue_.BeginTransaction()); |
241 const auto sequence_and_sort_key = transaction->Peek(); | 241 const auto& sequence_and_sort_key = transaction->Peek(); |
242 | 242 |
243 if (sequence_and_sort_key.is_null()) { | 243 if (sequence_and_sort_key.is_null()) { |
244 // |transaction| is kept alive while |worker_thread| is added to | 244 // |transaction| is kept alive while |worker_thread| is added to |
245 // |idle_worker_threads_stack_| to avoid this race: | 245 // |idle_worker_threads_stack_| to avoid this race: |
246 // 1. This thread creates a Transaction, finds |shared_priority_queue_| | 246 // 1. This thread creates a Transaction, finds |shared_priority_queue_| |
247 // empty and ends the Transaction. | 247 // empty and ends the Transaction. |
248 // 2. Other thread creates a Transaction, inserts a Sequence into | 248 // 2. Other thread creates a Transaction, inserts a Sequence into |
249 // |shared_priority_queue_| and ends the Transaction. This can't happen | 249 // |shared_priority_queue_| and ends the Transaction. This can't happen |
250 // if the Transaction of step 1 is still active because because there can | 250 // if the Transaction of step 1 is still active because because there can |
251 // only be one active Transaction per PriorityQueue at a time. | 251 // only be one active Transaction per PriorityQueue at a time. |
252 // 3. Other thread calls WakeUpOneThread(). No thread is woken up because | 252 // 3. Other thread calls WakeUpOneThread(). No thread is woken up because |
253 // |idle_worker_threads_stack_| is empty. | 253 // |idle_worker_threads_stack_| is empty. |
254 // 4. This thread adds itself to |idle_worker_threads_stack_| and goes to | 254 // 4. This thread adds itself to |idle_worker_threads_stack_| and goes to |
255 // sleep. No thread runs the Sequence inserted in step 2. | 255 // sleep. No thread runs the Sequence inserted in step 2. |
256 outer_->AddToIdleWorkerThreadsStack(worker_thread); | 256 outer_->AddToIdleWorkerThreadsStack(worker_thread); |
257 return nullptr; | 257 return nullptr; |
258 } | 258 } |
259 | 259 |
| 260 scoped_refptr<Sequence> sequence = sequence_and_sort_key.sequence; |
260 transaction->Pop(); | 261 transaction->Pop(); |
261 return sequence_and_sort_key.sequence; | 262 return sequence; |
262 } | 263 } |
263 | 264 |
264 void SchedulerThreadPool::SchedulerWorkerThreadDelegateImpl::EnqueueSequence( | 265 void SchedulerThreadPool::SchedulerWorkerThreadDelegateImpl::EnqueueSequence( |
265 scoped_refptr<Sequence> sequence) { | 266 scoped_refptr<Sequence> sequence) { |
266 enqueue_sequence_callback_.Run(std::move(sequence)); | 267 enqueue_sequence_callback_.Run(std::move(sequence)); |
267 } | 268 } |
268 | 269 |
269 SchedulerThreadPool::SchedulerThreadPool( | 270 SchedulerThreadPool::SchedulerThreadPool( |
270 const EnqueueSequenceCallback& enqueue_sequence_callback, | 271 const EnqueueSequenceCallback& enqueue_sequence_callback, |
271 TaskTracker* task_tracker) | 272 TaskTracker* task_tracker) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 if (idle_worker_threads_stack_.empty()) | 322 if (idle_worker_threads_stack_.empty()) |
322 return nullptr; | 323 return nullptr; |
323 | 324 |
324 auto worker_thread = idle_worker_threads_stack_.top(); | 325 auto worker_thread = idle_worker_threads_stack_.top(); |
325 idle_worker_threads_stack_.pop(); | 326 idle_worker_threads_stack_.pop(); |
326 return worker_thread; | 327 return worker_thread; |
327 } | 328 } |
328 | 329 |
329 } // namespace internal | 330 } // namespace internal |
330 } // namespace base | 331 } // namespace base |
OLD | NEW |