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 |