| 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 |