| Index: base/task_scheduler/scheduler_worker_pool_impl.cc
|
| diff --git a/base/task_scheduler/scheduler_worker_pool_impl.cc b/base/task_scheduler/scheduler_worker_pool_impl.cc
|
| index 93800eb33b754e11d261ef11b4e1046e1774d5da..2dcde1b1160253e5a657f07e3424a2bb2b004288 100644
|
| --- a/base/task_scheduler/scheduler_worker_pool_impl.cc
|
| +++ b/base/task_scheduler/scheduler_worker_pool_impl.cc
|
| @@ -150,9 +150,12 @@ class SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner :
|
| // tasks so long as |worker_pool| and |worker| are alive.
|
| // TODO(robliao): Find a concrete way to manage the memory of |worker_pool|
|
| // and |worker|.
|
| - SchedulerSingleThreadTaskRunner(const TaskTraits& traits,
|
| - SchedulerWorkerPool* worker_pool,
|
| - SchedulerWorker* worker);
|
| + SchedulerSingleThreadTaskRunner(
|
| + const TaskTraits& traits,
|
| + SchedulerWorkerPool* worker_pool,
|
| + SchedulerWorker* worker,
|
| + UnregisterSingleThreadWorkerPoolCallback
|
| + unregister_single_thread_worker_pool_callback);
|
|
|
| // SingleThreadTaskRunner:
|
| bool PostDelayedTask(const tracked_objects::Location& from_here,
|
| @@ -284,11 +287,23 @@ std::unique_ptr<SchedulerWorkerPoolImpl> SchedulerWorkerPoolImpl::Create(
|
| const ReEnqueueSequenceCallback& re_enqueue_sequence_callback,
|
| TaskTracker* task_tracker,
|
| DelayedTaskManager* delayed_task_manager) {
|
| - auto worker_pool = WrapUnique(
|
| - new SchedulerWorkerPoolImpl(params, task_tracker, delayed_task_manager));
|
| - if (worker_pool->Initialize(params, re_enqueue_sequence_callback))
|
| - return worker_pool;
|
| - return nullptr;
|
| + return CreateInternal(params, task_tracker, delayed_task_manager,
|
| + re_enqueue_sequence_callback,
|
| + UnregisterSingleThreadWorkerPoolCallback());
|
| +}
|
| +
|
| +// static
|
| +std::unique_ptr<SchedulerWorkerPoolImpl>
|
| +SchedulerWorkerPoolImpl::CreateSingleThreadWorkerPool(
|
| + const SchedulerWorkerPoolParams& params,
|
| + UnregisterSingleThreadWorkerPoolCallback
|
| + unregister_single_thread_worker_pool_callback,
|
| + TaskTracker* task_tracker,
|
| + DelayedTaskManager* delayed_task_manager) {
|
| + DCHECK_EQ(params.max_threads(), 1U);
|
| + return CreateInternal(params, task_tracker, delayed_task_manager,
|
| + ReEnqueueSequenceCallback(),
|
| + unregister_single_thread_worker_pool_callback);
|
| }
|
|
|
| scoped_refptr<TaskRunner> SchedulerWorkerPoolImpl::CreateTaskRunnerWithTraits(
|
| @@ -305,6 +320,7 @@ SchedulerWorkerPoolImpl::CreateSequencedTaskRunnerWithTraits(
|
| scoped_refptr<SingleThreadTaskRunner>
|
| SchedulerWorkerPoolImpl::CreateSingleThreadTaskRunnerWithTraits(
|
| const TaskTraits& traits) {
|
| + DCHECK(unregister_single_thread_worker_pool_callback_);
|
| // TODO(fdoray): Find a way to take load into account when assigning a
|
| // SchedulerWorker to a SingleThreadTaskRunner.
|
| size_t worker_index;
|
| @@ -314,7 +330,8 @@ SchedulerWorkerPoolImpl::CreateSingleThreadTaskRunnerWithTraits(
|
| next_worker_index_ = (next_worker_index_ + 1) % workers_.size();
|
| }
|
| return make_scoped_refptr(new SchedulerSingleThreadTaskRunner(
|
| - traits, this, workers_[worker_index].get()));
|
| + traits, this, workers_[worker_index].get(),
|
| + unregister_single_thread_worker_pool_callback_));
|
| }
|
|
|
| void SchedulerWorkerPoolImpl::ReEnqueueSequence(
|
| @@ -433,12 +450,13 @@ size_t SchedulerWorkerPoolImpl::NumberOfAliveWorkersForTesting() {
|
| }
|
|
|
| SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner::
|
| - SchedulerSingleThreadTaskRunner(const TaskTraits& traits,
|
| - SchedulerWorkerPool* worker_pool,
|
| - SchedulerWorker* worker)
|
| - : traits_(traits),
|
| - worker_pool_(worker_pool),
|
| - worker_(worker) {
|
| + SchedulerSingleThreadTaskRunner(
|
| + const TaskTraits& traits,
|
| + SchedulerWorkerPool* worker_pool,
|
| + SchedulerWorker* worker,
|
| + UnregisterSingleThreadWorkerPoolCallback
|
| + unregister_single_thread_worker_pool_callback)
|
| + : traits_(traits), worker_pool_(worker_pool), worker_(worker) {
|
| DCHECK(worker_pool_);
|
| DCHECK(worker_);
|
| static_cast<SchedulerWorkerDelegateImpl*>(worker_->delegate())->
|
| @@ -449,6 +467,9 @@ SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner::
|
| ~SchedulerSingleThreadTaskRunner() {
|
| static_cast<SchedulerWorkerDelegateImpl*>(worker_->delegate())->
|
| UnregisterSingleThreadTaskRunner();
|
| + auto worker_pool_impl = static_cast<SchedulerWorkerPoolImpl*>(worker_pool_);
|
| + worker_pool_impl->unregister_single_thread_worker_pool_callback_.Run(
|
| + worker_pool_impl);
|
| }
|
|
|
| SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::
|
| @@ -606,8 +627,14 @@ bool SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::CanDetach(
|
| const bool can_detach =
|
| !idle_start_time_.is_null() &&
|
| (TimeTicks::Now() - idle_start_time_) > outer_->suggested_reclaim_time_ &&
|
| - worker != outer_->PeekAtIdleWorkersStack() &&
|
| - !subtle::NoBarrier_Load(&num_single_threaded_runners_) &&
|
| + // In a pool which runs sequenced and parallel tasks, always keep
|
| + // on idle thread alive. In a pool which runs single-threaded tasks,
|
| + // keep the thread alive only when there are active TaskRunners.
|
| + (worker != outer_->PeekAtIdleWorkersStack() ||
|
| + (outer_->unregister_single_thread_worker_pool_callback_ &&
|
| + !subtle::NoBarrier_Load(&num_single_threaded_runners_))) &&
|
| + outer_->CanWorkerDetachForTesting();
|
| + !subtle::NoBarrier_Load(&num_single_threaded_runners_) &&
|
| outer_->CanWorkerDetachForTesting();
|
| return can_detach;
|
| }
|
| @@ -620,10 +647,29 @@ void SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::OnDetach() {
|
| last_detach_time_ = TimeTicks::Now();
|
| }
|
|
|
| +// static
|
| +std::unique_ptr<SchedulerWorkerPoolImpl>
|
| +SchedulerWorkerPoolImpl::CreateInternal(
|
| + const SchedulerWorkerPoolParams& params,
|
| + TaskTracker* task_tracker,
|
| + DelayedTaskManager* delayed_task_manager,
|
| + const ReEnqueueSequenceCallback& re_enqueue_sequence_callback,
|
| + UnregisterSingleThreadWorkerPoolCallback
|
| + unregister_single_thread_worker_callback) {
|
| + auto worker_pool = WrapUnique(
|
| + new SchedulerWorkerPoolImpl(params, task_tracker, delayed_task_manager,
|
| + unregister_single_thread_worker_callback));
|
| + if (worker_pool->Initialize(params, re_enqueue_sequence_callback))
|
| + return worker_pool;
|
| + return nullptr;
|
| +}
|
| +
|
| SchedulerWorkerPoolImpl::SchedulerWorkerPoolImpl(
|
| const SchedulerWorkerPoolParams& params,
|
| TaskTracker* task_tracker,
|
| - DelayedTaskManager* delayed_task_manager)
|
| + DelayedTaskManager* delayed_task_manager,
|
| + UnregisterSingleThreadWorkerPoolCallback
|
| + unregister_single_thread_worker_pool_callback)
|
| : name_(params.name()),
|
| suggested_reclaim_time_(params.suggested_reclaim_time()),
|
| idle_workers_stack_lock_(shared_priority_queue_.container_lock()),
|
| @@ -662,7 +708,9 @@ SchedulerWorkerPoolImpl::SchedulerWorkerPoolImpl(
|
| 50,
|
| HistogramBase::kUmaTargetedHistogramFlag)),
|
| task_tracker_(task_tracker),
|
| - delayed_task_manager_(delayed_task_manager) {
|
| + delayed_task_manager_(delayed_task_manager),
|
| + unregister_single_thread_worker_pool_callback_(
|
| + unregister_single_thread_worker_pool_callback) {
|
| DCHECK(task_tracker_);
|
| DCHECK(delayed_task_manager_);
|
| }
|
|
|