| Index: base/task_scheduler/task_scheduler_impl.cc
|
| diff --git a/base/task_scheduler/task_scheduler_impl.cc b/base/task_scheduler/task_scheduler_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..42b7ca89f1ba5fe55e96f3bb697967ed0c54a737
|
| --- /dev/null
|
| +++ b/base/task_scheduler/task_scheduler_impl.cc
|
| @@ -0,0 +1,111 @@
|
| +// Copyright 2016 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/task_scheduler_impl.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/logging.h"
|
| +#include "base/task_scheduler/worker_thread.h"
|
| +
|
| +namespace base {
|
| +namespace internal {
|
| +
|
| +TaskSchedulerImpl::TaskSchedulerImpl() {
|
| + // Using Unretained() is safe because a TaskSchedulerImpl is never destroyed
|
| + // before all its ThreadPools have been destroyed.
|
| + const WorkerThread::ReinsertSequenceCallback reinsert_sequence_callback =
|
| + Bind(&TaskSchedulerImpl::ReinsertSequenceCallback, Unretained(this));
|
| +
|
| + background_thread_pool_ = ThreadPool::CreateThreadPool(
|
| + ThreadPriority::BACKGROUND, 1, reinsert_sequence_callback,
|
| + &shutdown_manager_);
|
| + CHECK(background_thread_pool_.get());
|
| +
|
| + background_file_io_thread_pool_ = ThreadPool::CreateThreadPool(
|
| + ThreadPriority::BACKGROUND, 1, reinsert_sequence_callback,
|
| + &shutdown_manager_);
|
| + CHECK(background_file_io_thread_pool_.get());
|
| +
|
| + normal_thread_pool_ = ThreadPool::CreateThreadPool(ThreadPriority::NORMAL, 4,
|
| + reinsert_sequence_callback,
|
| + &shutdown_manager_);
|
| + CHECK(normal_thread_pool_.get());
|
| +
|
| + normal_file_io_thread_pool_ = ThreadPool::CreateThreadPool(
|
| + ThreadPriority::NORMAL, 12, reinsert_sequence_callback,
|
| + &shutdown_manager_);
|
| + CHECK(normal_file_io_thread_pool_.get());
|
| +}
|
| +
|
| +TaskSchedulerImpl::~TaskSchedulerImpl() {
|
| + // In production code, a TaskSchedulerImpl is never destroyed. In test code,
|
| + // ShutdownAndJoinAllThreadsForTesting() must be called before the
|
| + // TaskSchedulerImpl is destroyed.
|
| + DCHECK(!background_thread_pool_.get());
|
| + DCHECK(!background_file_io_thread_pool_.get());
|
| + DCHECK(!normal_thread_pool_.get());
|
| + DCHECK(!normal_file_io_thread_pool_.get());
|
| +}
|
| +
|
| +void TaskSchedulerImpl::PostTaskWithTraits(
|
| + const tracked_objects::Location& from_here,
|
| + TaskTraits traits,
|
| + const Closure& task) {
|
| + CreateTaskRunnerWithTraits(traits, ExecutionMode::PARALLEL)
|
| + ->PostTask(from_here, task);
|
| +}
|
| +
|
| +scoped_refptr<TaskRunner> TaskSchedulerImpl::CreateTaskRunnerWithTraits(
|
| + TaskTraits traits,
|
| + ExecutionMode execution_mode) {
|
| + return GetThreadPoolForTraits(traits)
|
| + ->CreateTaskRunnerWithTraits(traits, execution_mode);
|
| +}
|
| +
|
| +void TaskSchedulerImpl::Shutdown() {
|
| + // TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown.
|
| + shutdown_manager_.Shutdown();
|
| +}
|
| +
|
| +void TaskSchedulerImpl::ShutdownAndJoinAllThreadsForTesting() {
|
| + background_thread_pool_->ShutdownAndJoinAllThreadsForTesting();
|
| + background_thread_pool_.reset();
|
| + background_file_io_thread_pool_->ShutdownAndJoinAllThreadsForTesting();
|
| + background_file_io_thread_pool_.reset();
|
| + normal_thread_pool_->ShutdownAndJoinAllThreadsForTesting();
|
| + normal_thread_pool_.reset();
|
| + normal_file_io_thread_pool_->ShutdownAndJoinAllThreadsForTesting();
|
| + normal_file_io_thread_pool_.reset();
|
| +}
|
| +
|
| +ThreadPool* TaskSchedulerImpl::GetThreadPoolForTraits(
|
| + const TaskTraits& traits) {
|
| + if (traits.with_file_io()) {
|
| + if (traits.priority() == TaskPriority::BACKGROUND)
|
| + return background_file_io_thread_pool_.get();
|
| + return normal_file_io_thread_pool_.get();
|
| + }
|
| +
|
| + if (traits.priority() == TaskPriority::BACKGROUND)
|
| + return background_thread_pool_.get();
|
| + return normal_thread_pool_.get();
|
| +}
|
| +
|
| +void TaskSchedulerImpl::ReinsertSequenceCallback(
|
| + scoped_refptr<Sequence> sequence,
|
| + const WorkerThread* worker_thread) {
|
| + const SequenceSortKey sort_key = sequence->GetSortKey();
|
| + const Task* next_task_in_sequence = sequence->PeekTask();
|
| + DCHECK(next_task_in_sequence);
|
| +
|
| + TaskTraits traits = TaskTraits().WithPriority(sort_key.priority());
|
| + if (next_task_in_sequence->traits.with_file_io())
|
| + traits = traits.WithFileIO();
|
| +
|
| + GetThreadPoolForTraits(traits)
|
| + ->ReinsertSequence(sequence, sort_key, worker_thread);
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace base
|
|
|