blob: 2b69a2900989a0c8243e186490673bf3bdb7dcfc [file] [log] [blame]
// 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.
#ifndef BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_
#define BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/task/common/checked_lock.h"
#include "base/task/single_thread_task_runner_thread_mode.h"
#include "base/task/thread_pool/environment_config.h"
#include "base/task/thread_pool/tracked_ref.h"
#include "base/thread_annotations.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
namespace base {
class TaskTraits;
class WorkerThreadObserver;
class SingleThreadTaskRunner;
namespace internal {
class DelayedTaskManager;
class WorkerThread;
class TaskTracker;
namespace {
class WorkerThreadDelegate;
} // namespace
// Manages a group of threads which are each associated with one or more
// SingleThreadTaskRunners.
//
// SingleThreadTaskRunners using SingleThreadTaskRunnerThreadMode::SHARED are
// backed by shared WorkerThreads for each COM+task environment combination.
// These workers are lazily instantiated and then only reclaimed during
// JoinForTesting()
//
// No threads are created (and hence no tasks can run) before Start() is called.
//
// This class is thread-safe.
class BASE_EXPORT PooledSingleThreadTaskRunnerManager final {
public:
PooledSingleThreadTaskRunnerManager(TrackedRef<TaskTracker> task_tracker,
DelayedTaskManager* delayed_task_manager);
~PooledSingleThreadTaskRunnerManager();
// Starts threads for existing SingleThreadTaskRunners and allows threads to
// be started when SingleThreadTaskRunners are created in the future. If
// specified, |worker_thread_observer| will be notified when a worker
// enters and exits its main function. It must not be destroyed before
// JoinForTesting() has returned (must never be destroyed in production).
void Start(WorkerThreadObserver* worker_thread_observer = nullptr);
// Wakes up workers as appropriate for the new CanRunPolicy policy. Must be
// called after an update to CanRunPolicy in TaskTracker.
void DidUpdateCanRunPolicy();
// Creates a SingleThreadTaskRunner which runs tasks with |traits| on a thread
// named "ThreadPoolSingleThread[Shared]" +
// kEnvironmentParams[GetEnvironmentIndexForTraits(traits)].name_suffix +
// index.
scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner(
const TaskTraits& traits,
SingleThreadTaskRunnerThreadMode thread_mode);
#if defined(OS_WIN)
// Creates a SingleThreadTaskRunner which runs tasks with |traits| on a COM
// STA thread named "ThreadPoolSingleThreadCOMSTA[Shared]" +
// kEnvironmentParams[GetEnvironmentIndexForTraits(traits)].name_suffix +
// index.
scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner(
const TaskTraits& traits,
SingleThreadTaskRunnerThreadMode thread_mode);
#endif // defined(OS_WIN)
void JoinForTesting();
private:
class PooledSingleThreadTaskRunner;
enum ContinueOnShutdown {
IS_CONTINUE_ON_SHUTDOWN,
IS_NOT_CONTINUE_ON_SHUTDOWN,
CONTINUE_ON_SHUTDOWN_COUNT,
};
static ContinueOnShutdown TraitsToContinueOnShutdown(
const TaskTraits& traits);
template <typename DelegateType>
scoped_refptr<PooledSingleThreadTaskRunner> CreateTaskRunnerImpl(
const TaskTraits& traits,
SingleThreadTaskRunnerThreadMode thread_mode);
template <typename DelegateType>
std::unique_ptr<WorkerThreadDelegate> CreateWorkerThreadDelegate(
const std::string& name,
int id,
SingleThreadTaskRunnerThreadMode thread_mode);
template <typename DelegateType>
WorkerThread* CreateAndRegisterWorkerThread(
const std::string& name,
SingleThreadTaskRunnerThreadMode thread_mode,
ThreadPriority priority_hint) EXCLUSIVE_LOCKS_REQUIRED(lock_);
template <typename DelegateType>
WorkerThread*& GetSharedWorkerThreadForTraits(const TaskTraits& traits);
void UnregisterWorkerThread(WorkerThread* worker);
void ReleaseSharedWorkerThreads();
const TrackedRef<TaskTracker> task_tracker_;
DelayedTaskManager* const delayed_task_manager_;
// Optional observer notified when a worker enters and exits its main
// function. Set in Start() and never modified afterwards.
WorkerThreadObserver* worker_thread_observer_ = nullptr;
CheckedLock lock_;
std::vector<scoped_refptr<WorkerThread>> workers_ GUARDED_BY(lock_);
int next_worker_id_ GUARDED_BY(lock_) = 0;
// Workers for SingleThreadTaskRunnerThreadMode::SHARED tasks. It is
// important to have separate threads for CONTINUE_ON_SHUTDOWN and non-
// CONTINUE_ON_SHUTDOWN to avoid being in a situation where a
// CONTINUE_ON_SHUTDOWN task effectively blocks shutdown by preventing a
// BLOCK_SHUTDOWN task to be scheduled. https://crbug.com/829786
WorkerThread* shared_worker_threads_[ENVIRONMENT_COUNT]
[CONTINUE_ON_SHUTDOWN_COUNT] GUARDED_BY(
lock_) = {};
#if defined(OS_WIN)
WorkerThread* shared_com_worker_threads_
[ENVIRONMENT_COUNT][CONTINUE_ON_SHUTDOWN_COUNT] GUARDED_BY(lock_) = {};
#endif // defined(OS_WIN)
// Set to true when Start() is called.
bool started_ GUARDED_BY(lock_) = false;
DISALLOW_COPY_AND_ASSIGN(PooledSingleThreadTaskRunnerManager);
};
} // namespace internal
} // namespace base
#endif // BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_