| Index: base/task_scheduler/scheduler_single_thread_task_runner_manager.cc
|
| diff --git a/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc b/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc
|
| deleted file mode 100644
|
| index 71f9c0bfb9383e4e16b5f21f02c29b70cbfcd566..0000000000000000000000000000000000000000
|
| --- a/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc
|
| +++ /dev/null
|
| @@ -1,274 +0,0 @@
|
| -// Copyright 2017 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h"
|
| -
|
| -#include <algorithm>
|
| -#include <memory>
|
| -#include <string>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/synchronization/atomic_flag.h"
|
| -#include "base/task_scheduler/delayed_task_manager.h"
|
| -#include "base/task_scheduler/scheduler_worker.h"
|
| -#include "base/task_scheduler/sequence.h"
|
| -#include "base/task_scheduler/task.h"
|
| -#include "base/task_scheduler/task_tracker.h"
|
| -#include "base/task_scheduler/task_traits.h"
|
| -#include "base/threading/platform_thread.h"
|
| -#include "base/time/time.h"
|
| -
|
| -namespace base {
|
| -namespace internal {
|
| -
|
| -namespace {
|
| -
|
| -// Allows for checking the PlatformThread::CurrentRef() against a set
|
| -// PlatformThreadRef atomically without using locks.
|
| -class AtomicThreadRefChecker {
|
| - public:
|
| - AtomicThreadRefChecker() = default;
|
| - ~AtomicThreadRefChecker() = default;
|
| -
|
| - void Set() {
|
| - thread_ref_ = PlatformThread::CurrentRef();
|
| - is_set_.Set();
|
| - }
|
| -
|
| - bool IsCurrentThreadSameAsSetThread() {
|
| - return is_set_.IsSet() && thread_ref_ == PlatformThread::CurrentRef();
|
| - }
|
| -
|
| - private:
|
| - AtomicFlag is_set_;
|
| - PlatformThreadRef thread_ref_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(AtomicThreadRefChecker);
|
| -};
|
| -
|
| -class SchedulerWorkerDelegate : public SchedulerWorker::Delegate {
|
| - public:
|
| - SchedulerWorkerDelegate(const std::string& thread_name)
|
| - : thread_name_(thread_name) {}
|
| -
|
| - // SchedulerWorker::Delegate:
|
| - void OnMainEntry(SchedulerWorker* worker) override {
|
| - thread_ref_checker_.Set();
|
| - PlatformThread::SetName(thread_name_);
|
| - }
|
| -
|
| - scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override {
|
| - AutoSchedulerLock auto_lock(sequence_lock_);
|
| - return std::move(sequence_);
|
| - }
|
| -
|
| - void DidRunTask() override {}
|
| -
|
| - void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override {
|
| - AutoSchedulerLock auto_lock(sequence_lock_);
|
| - DCHECK(!sequence_);
|
| - sequence_ = std::move(sequence);
|
| - }
|
| -
|
| - TimeDelta GetSleepTimeout() override { return TimeDelta::Max(); }
|
| -
|
| - bool CanDetach(SchedulerWorker* worker) override { return false; }
|
| -
|
| - void OnDetach() override { NOTREACHED(); }
|
| -
|
| - bool RunsTasksOnCurrentThread() {
|
| - // We check the thread ref instead of the sequence for the benefit of COM
|
| - // callbacks which may execute without a sequence context.
|
| - return thread_ref_checker_.IsCurrentThreadSameAsSetThread();
|
| - }
|
| -
|
| - private:
|
| - const std::string thread_name_;
|
| -
|
| - // Synchronizes access to |sequence_| and handles the fact that
|
| - // ReEnqueueSequence() is called on both the worker thread for reenqueuing
|
| - // the sequence and off of the worker thread to seed the sequence for
|
| - // GetWork().
|
| - SchedulerLock sequence_lock_;
|
| - scoped_refptr<Sequence> sequence_;
|
| -
|
| - AtomicThreadRefChecker thread_ref_checker_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDelegate);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -class SchedulerSingleThreadTaskRunnerManager::SchedulerSingleThreadTaskRunner
|
| - : public SingleThreadTaskRunner {
|
| - public:
|
| - // Constructs a SchedulerSingleThreadTaskRunner that indirectly controls the
|
| - // lifetime of a dedicated |worker| for |traits|.
|
| - SchedulerSingleThreadTaskRunner(
|
| - SchedulerSingleThreadTaskRunnerManager* const outer,
|
| - const TaskTraits& traits,
|
| - SchedulerWorker* worker)
|
| - : outer_(outer), traits_(traits), worker_(worker) {
|
| - DCHECK(outer_);
|
| - DCHECK(worker_);
|
| - }
|
| -
|
| - // SingleThreadTaskRunner:
|
| - bool PostDelayedTask(const tracked_objects::Location& from_here,
|
| - const Closure& closure,
|
| - TimeDelta delay) override;
|
| -
|
| - bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
|
| - const Closure& closure,
|
| - base::TimeDelta delay) override {
|
| - // Tasks are never nested within the task scheduler.
|
| - return PostDelayedTask(from_here, closure, delay);
|
| - }
|
| -
|
| - bool RunsTasksOnCurrentThread() const override {
|
| - auto* delegate = static_cast<SchedulerWorkerDelegate*>(worker_->delegate());
|
| - return delegate->RunsTasksOnCurrentThread();
|
| - }
|
| -
|
| - private:
|
| - ~SchedulerSingleThreadTaskRunner() override {
|
| - outer_->UnregisterSchedulerWorker(worker_);
|
| - }
|
| -
|
| - void PostTaskNow(std::unique_ptr<Task> task);
|
| -
|
| - // Sequence for all Tasks posted through this TaskRunner.
|
| - const scoped_refptr<Sequence> sequence_ = new Sequence;
|
| -
|
| - SchedulerSingleThreadTaskRunnerManager* const outer_;
|
| - const TaskTraits traits_;
|
| - SchedulerWorker* const worker_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SchedulerSingleThreadTaskRunner);
|
| -};
|
| -
|
| -bool SchedulerSingleThreadTaskRunnerManager::SchedulerSingleThreadTaskRunner::
|
| - PostDelayedTask(const tracked_objects::Location& from_here,
|
| - const Closure& closure,
|
| - TimeDelta delay) {
|
| - auto task = MakeUnique<Task>(from_here, closure, traits_, delay);
|
| - task->single_thread_task_runner_ref = this;
|
| -
|
| - if (!outer_->task_tracker_->WillPostTask(task.get()))
|
| - return false;
|
| -
|
| - if (task->delayed_run_time.is_null()) {
|
| - PostTaskNow(std::move(task));
|
| - } else {
|
| - outer_->delayed_task_manager_->AddDelayedTask(
|
| - std::move(task),
|
| - Bind(&SchedulerSingleThreadTaskRunner::PostTaskNow, Unretained(this)));
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -void SchedulerSingleThreadTaskRunnerManager::SchedulerSingleThreadTaskRunner::
|
| - PostTaskNow(std::unique_ptr<Task> task) {
|
| - const bool sequence_was_empty = sequence_->PushTask(std::move(task));
|
| - if (sequence_was_empty) {
|
| - auto* delegate = static_cast<SchedulerWorkerDelegate*>(worker_->delegate());
|
| - delegate->ReEnqueueSequence(sequence_);
|
| - worker_->WakeUp();
|
| - }
|
| -}
|
| -
|
| -SchedulerSingleThreadTaskRunnerManager::SchedulerSingleThreadTaskRunnerManager(
|
| - const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector,
|
| - const TaskScheduler::WorkerPoolIndexForTraitsCallback&
|
| - worker_pool_index_for_traits_callback,
|
| - TaskTracker* task_tracker,
|
| - DelayedTaskManager* delayed_task_manager)
|
| - : worker_pool_params_vector_(worker_pool_params_vector),
|
| - worker_pool_index_for_traits_callback_(
|
| - worker_pool_index_for_traits_callback),
|
| - task_tracker_(task_tracker),
|
| - delayed_task_manager_(delayed_task_manager) {
|
| - DCHECK_GT(worker_pool_params_vector_.size(), 0U);
|
| - DCHECK(worker_pool_index_for_traits_callback_);
|
| - DCHECK(task_tracker_);
|
| - DCHECK(delayed_task_manager_);
|
| -}
|
| -
|
| -SchedulerSingleThreadTaskRunnerManager::
|
| - ~SchedulerSingleThreadTaskRunnerManager() {
|
| - DCHECK(workers_.empty()) << "SchedulerSingleThreadTaskRunners must outlive "
|
| - "SchedulerSingleThreadTaskRunnerManager";
|
| -}
|
| -
|
| -scoped_refptr<SingleThreadTaskRunner>
|
| -SchedulerSingleThreadTaskRunnerManager::CreateSingleThreadTaskRunnerWithTraits(
|
| - const TaskTraits& traits) {
|
| - size_t index = worker_pool_index_for_traits_callback_.Run(traits);
|
| - DCHECK_LT(index, worker_pool_params_vector_.size());
|
| - return new SchedulerSingleThreadTaskRunner(
|
| - this, traits,
|
| - CreateAndRegisterSchedulerWorker(worker_pool_params_vector_[index]));
|
| -}
|
| -
|
| -void SchedulerSingleThreadTaskRunnerManager::JoinForTesting() {
|
| - decltype(workers_) local_workers;
|
| - {
|
| - AutoSchedulerLock auto_lock(workers_lock_);
|
| - local_workers = std::move(workers_);
|
| - }
|
| -
|
| - for (const auto& worker : local_workers)
|
| - worker->JoinForTesting();
|
| -
|
| - {
|
| - AutoSchedulerLock auto_lock(workers_lock_);
|
| - DCHECK(workers_.empty())
|
| - << "New worker(s) unexpectedly registered during join.";
|
| - workers_ = std::move(local_workers);
|
| - }
|
| -}
|
| -
|
| -SchedulerWorker*
|
| -SchedulerSingleThreadTaskRunnerManager::CreateAndRegisterSchedulerWorker(
|
| - const SchedulerWorkerPoolParams& params) {
|
| - AutoSchedulerLock auto_lock(workers_lock_);
|
| - int id = next_worker_id_++;
|
| - auto delegate = MakeUnique<SchedulerWorkerDelegate>(base::StringPrintf(
|
| - "TaskSchedulerSingleThreadWorker%d%s", id, params.name().c_str()));
|
| - workers_.emplace_back(SchedulerWorker::Create(
|
| - params.priority_hint(), std::move(delegate), task_tracker_,
|
| - SchedulerWorker::InitialState::DETACHED));
|
| - return workers_.back().get();
|
| -}
|
| -
|
| -void SchedulerSingleThreadTaskRunnerManager::UnregisterSchedulerWorker(
|
| - SchedulerWorker* worker) {
|
| - // Cleanup uses a SchedulerLock, so call Cleanup() after releasing
|
| - // |workers_lock_|.
|
| - scoped_refptr<SchedulerWorker> worker_to_destroy;
|
| - {
|
| - AutoSchedulerLock auto_lock(workers_lock_);
|
| -
|
| - // We might be joining, so no-op this if |workers_| is empty.
|
| - if (workers_.empty())
|
| - return;
|
| -
|
| - auto worker_iter =
|
| - std::find_if(workers_.begin(), workers_.end(),
|
| - [worker](const scoped_refptr<SchedulerWorker>& candidate) {
|
| - return candidate.get() == worker;
|
| - });
|
| - DCHECK(worker_iter != workers_.end());
|
| - worker_to_destroy = std::move(*worker_iter);
|
| - workers_.erase(worker_iter);
|
| - }
|
| - worker_to_destroy->Cleanup();
|
| -}
|
| -
|
| -} // namespace internal
|
| -} // namespace base
|
|
|