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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 | 285 |
| 286 DISALLOW_COPY_AND_ASSIGN(Worker); | 286 DISALLOW_COPY_AND_ASSIGN(Worker); |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 // Inner ---------------------------------------------------------------------- | 289 // Inner ---------------------------------------------------------------------- |
| 290 | 290 |
| 291 class SequencedWorkerPool::Inner { | 291 class SequencedWorkerPool::Inner { |
| 292 public: | 292 public: |
| 293 // Take a raw pointer to |worker| to avoid cycles (since we're owned | 293 // Take a raw pointer to |worker| to avoid cycles (since we're owned |
| 294 // by it). | 294 // by it). |
| 295 Inner(SequencedWorkerPool* worker_pool, size_t max_threads, | 295 Inner(SequencedWorkerPool* worker_pool, |
| 296 size_t max_threads, | |
| 296 const std::string& thread_name_prefix, | 297 const std::string& thread_name_prefix, |
| 298 base::TaskPriority task_priority, | |
| 297 TestingObserver* observer); | 299 TestingObserver* observer); |
| 298 | 300 |
| 299 ~Inner(); | 301 ~Inner(); |
| 300 | 302 |
| 301 static SequenceToken GetSequenceToken(); | 303 static SequenceToken GetSequenceToken(); |
| 302 | 304 |
| 303 SequenceToken GetNamedSequenceToken(const std::string& name); | 305 SequenceToken GetNamedSequenceToken(const std::string& name); |
| 304 | 306 |
| 305 // This function accepts a name and an ID. If the name is null, the | 307 // This function accepts a name and an ID. If the name is null, the |
| 306 // token ID is used. This allows us to implement the optional name lookup | 308 // token ID is used. This allows us to implement the optional name lookup |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 // has been called. | 492 // has been called. |
| 491 int max_blocking_tasks_after_shutdown_; | 493 int max_blocking_tasks_after_shutdown_; |
| 492 | 494 |
| 493 // State used to cleanup for testing, all guarded by lock_. | 495 // State used to cleanup for testing, all guarded by lock_. |
| 494 CleanupState cleanup_state_; | 496 CleanupState cleanup_state_; |
| 495 size_t cleanup_idlers_; | 497 size_t cleanup_idlers_; |
| 496 ConditionVariable cleanup_cv_; | 498 ConditionVariable cleanup_cv_; |
| 497 | 499 |
| 498 TestingObserver* const testing_observer_; | 500 TestingObserver* const testing_observer_; |
| 499 | 501 |
| 502 // The TaskPriority to be used for SequencedWorkerPool tasks redirected to the | |
| 503 // TaskScheduler as an experiment (unused otherwise). | |
| 504 const base::TaskPriority task_priority_; | |
| 505 | |
| 500 DISALLOW_COPY_AND_ASSIGN(Inner); | 506 DISALLOW_COPY_AND_ASSIGN(Inner); |
| 501 }; | 507 }; |
| 502 | 508 |
| 503 // Worker definitions --------------------------------------------------------- | 509 // Worker definitions --------------------------------------------------------- |
| 504 | 510 |
| 505 SequencedWorkerPool::Worker::Worker( | 511 SequencedWorkerPool::Worker::Worker( |
| 506 scoped_refptr<SequencedWorkerPool> worker_pool, | 512 scoped_refptr<SequencedWorkerPool> worker_pool, |
| 507 int thread_number, | 513 int thread_number, |
| 508 const std::string& prefix) | 514 const std::string& prefix) |
| 509 : SimpleThread(prefix + StringPrintf("Worker%d", thread_number)), | 515 : SimpleThread(prefix + StringPrintf("Worker%d", thread_number)), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 | 551 |
| 546 return lazy_tls_ptr_.Get().Get(); | 552 return lazy_tls_ptr_.Get().Get(); |
| 547 } | 553 } |
| 548 | 554 |
| 549 // static | 555 // static |
| 550 LazyInstance<ThreadLocalPointer<SequencedWorkerPool::Worker>>::Leaky | 556 LazyInstance<ThreadLocalPointer<SequencedWorkerPool::Worker>>::Leaky |
| 551 SequencedWorkerPool::Worker::lazy_tls_ptr_ = LAZY_INSTANCE_INITIALIZER; | 557 SequencedWorkerPool::Worker::lazy_tls_ptr_ = LAZY_INSTANCE_INITIALIZER; |
| 552 | 558 |
| 553 // Inner definitions --------------------------------------------------------- | 559 // Inner definitions --------------------------------------------------------- |
| 554 | 560 |
| 555 SequencedWorkerPool::Inner::Inner( | 561 SequencedWorkerPool::Inner::Inner(SequencedWorkerPool* worker_pool, |
| 556 SequencedWorkerPool* worker_pool, | 562 size_t max_threads, |
| 557 size_t max_threads, | 563 const std::string& thread_name_prefix, |
| 558 const std::string& thread_name_prefix, | 564 base::TaskPriority task_priority, |
| 559 TestingObserver* observer) | 565 TestingObserver* observer) |
| 560 : worker_pool_(worker_pool), | 566 : worker_pool_(worker_pool), |
| 561 lock_(), | 567 lock_(), |
| 562 has_work_cv_(&lock_), | 568 has_work_cv_(&lock_), |
| 563 can_shutdown_cv_(&lock_), | 569 can_shutdown_cv_(&lock_), |
| 564 max_threads_(max_threads), | 570 max_threads_(max_threads), |
| 565 thread_name_prefix_(thread_name_prefix), | 571 thread_name_prefix_(thread_name_prefix), |
| 566 thread_being_created_(false), | 572 thread_being_created_(false), |
| 567 waiting_thread_count_(0), | 573 waiting_thread_count_(0), |
| 568 blocking_shutdown_thread_count_(0), | 574 blocking_shutdown_thread_count_(0), |
| 569 next_sequence_task_number_(0), | 575 next_sequence_task_number_(0), |
| 570 blocking_shutdown_pending_task_count_(0), | 576 blocking_shutdown_pending_task_count_(0), |
| 571 trace_id_(0), | 577 trace_id_(0), |
| 572 shutdown_called_(false), | 578 shutdown_called_(false), |
| 573 max_blocking_tasks_after_shutdown_(0), | 579 max_blocking_tasks_after_shutdown_(0), |
| 574 cleanup_state_(CLEANUP_DONE), | 580 cleanup_state_(CLEANUP_DONE), |
| 575 cleanup_idlers_(0), | 581 cleanup_idlers_(0), |
| 576 cleanup_cv_(&lock_), | 582 cleanup_cv_(&lock_), |
| 577 testing_observer_(observer) {} | 583 testing_observer_(observer), |
| 584 task_priority_(task_priority) {} | |
| 578 | 585 |
| 579 SequencedWorkerPool::Inner::~Inner() { | 586 SequencedWorkerPool::Inner::~Inner() { |
| 580 // You must call Shutdown() before destroying the pool. | 587 // You must call Shutdown() before destroying the pool. |
| 581 DCHECK(shutdown_called_); | 588 DCHECK(shutdown_called_); |
| 582 | 589 |
| 583 // Need to explicitly join with the threads before they're destroyed or else | 590 // Need to explicitly join with the threads before they're destroyed or else |
| 584 // they will be running when our object is half torn down. | 591 // they will be running when our object is half torn down. |
| 585 for (ThreadMap::iterator it = threads_.begin(); it != threads_.end(); ++it) | 592 for (ThreadMap::iterator it = threads_.begin(); it != threads_.end(); ++it) |
| 586 it->second->Join(); | 593 it->second->Join(); |
| 587 threads_.clear(); | 594 threads_.clear(); |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1247 pool->inner_->SetRunningTaskInfoForCurrentThread(sequence_token, | 1254 pool->inner_->SetRunningTaskInfoForCurrentThread(sequence_token, |
| 1248 shutdown_behavior); | 1255 shutdown_behavior); |
| 1249 } | 1256 } |
| 1250 | 1257 |
| 1251 DCHECK(pool->IsRunningSequenceOnCurrentThread(sequence_token)); | 1258 DCHECK(pool->IsRunningSequenceOnCurrentThread(sequence_token)); |
| 1252 return new SequencedWorkerPoolSequencedTaskRunner( | 1259 return new SequencedWorkerPoolSequencedTaskRunner( |
| 1253 std::move(pool), sequence_token, shutdown_behavior); | 1260 std::move(pool), sequence_token, shutdown_behavior); |
| 1254 } | 1261 } |
| 1255 | 1262 |
| 1256 SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, | 1263 SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, |
| 1257 const std::string& thread_name_prefix) | |
| 1258 : constructor_task_runner_(ThreadTaskRunnerHandle::Get()), | |
| 1259 inner_(new Inner(this, max_threads, thread_name_prefix, NULL)) { | |
| 1260 } | |
| 1261 | |
| 1262 SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, | |
| 1263 const std::string& thread_name_prefix, | 1264 const std::string& thread_name_prefix, |
| 1265 base::TaskPriority task_priority) | |
| 1266 : constructor_task_runner_(ThreadTaskRunnerHandle::Get()), | |
| 1267 inner_(new Inner(this, | |
|
danakj
2016/06/28 23:30:59
is this git cl formatted?
gab
2016/06/29 18:25:02
Yes.
| |
| 1268 max_threads, | |
| 1269 thread_name_prefix, | |
| 1270 task_priority, | |
| 1271 NULL)) {} | |
| 1272 | |
| 1273 SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, | |
| 1274 const std::string& thread_name_prefix, | |
| 1275 base::TaskPriority task_priority, | |
| 1264 TestingObserver* observer) | 1276 TestingObserver* observer) |
| 1265 : constructor_task_runner_(ThreadTaskRunnerHandle::Get()), | 1277 : constructor_task_runner_(ThreadTaskRunnerHandle::Get()), |
| 1266 inner_(new Inner(this, max_threads, thread_name_prefix, observer)) { | 1278 inner_(new Inner(this, |
| 1267 } | 1279 max_threads, |
| 1280 thread_name_prefix, | |
| 1281 task_priority, | |
| 1282 observer)) {} | |
| 1268 | 1283 |
| 1269 SequencedWorkerPool::~SequencedWorkerPool() {} | 1284 SequencedWorkerPool::~SequencedWorkerPool() {} |
| 1270 | 1285 |
| 1271 void SequencedWorkerPool::OnDestruct() const { | 1286 void SequencedWorkerPool::OnDestruct() const { |
| 1272 // Avoid deleting ourselves on a worker thread (which would deadlock). | 1287 // Avoid deleting ourselves on a worker thread (which would deadlock). |
| 1273 if (RunsTasksOnCurrentThread()) { | 1288 if (RunsTasksOnCurrentThread()) { |
| 1274 constructor_task_runner_->DeleteSoon(FROM_HERE, this); | 1289 constructor_task_runner_->DeleteSoon(FROM_HERE, this); |
| 1275 } else { | 1290 } else { |
| 1276 delete this; | 1291 delete this; |
| 1277 } | 1292 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1399 void SequencedWorkerPool::Shutdown(int max_new_blocking_tasks_after_shutdown) { | 1414 void SequencedWorkerPool::Shutdown(int max_new_blocking_tasks_after_shutdown) { |
| 1400 DCHECK(constructor_task_runner_->BelongsToCurrentThread()); | 1415 DCHECK(constructor_task_runner_->BelongsToCurrentThread()); |
| 1401 inner_->Shutdown(max_new_blocking_tasks_after_shutdown); | 1416 inner_->Shutdown(max_new_blocking_tasks_after_shutdown); |
| 1402 } | 1417 } |
| 1403 | 1418 |
| 1404 bool SequencedWorkerPool::IsShutdownInProgress() { | 1419 bool SequencedWorkerPool::IsShutdownInProgress() { |
| 1405 return inner_->IsShutdownInProgress(); | 1420 return inner_->IsShutdownInProgress(); |
| 1406 } | 1421 } |
| 1407 | 1422 |
| 1408 } // namespace base | 1423 } // namespace base |
| OLD | NEW |