• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_
6 #define BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/base_export.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/task/common/checked_lock.h"
15 #include "base/task/single_thread_task_runner_thread_mode.h"
16 #include "base/task/thread_pool/environment_config.h"
17 #include "base/task/thread_pool/tracked_ref.h"
18 #include "base/thread_annotations.h"
19 #include "base/threading/platform_thread.h"
20 #include "build/build_config.h"
21 
22 namespace base {
23 
24 class TaskTraits;
25 class WorkerThreadObserver;
26 class SingleThreadTaskRunner;
27 
28 namespace internal {
29 
30 class DelayedTaskManager;
31 class WorkerThread;
32 class TaskTracker;
33 
34 namespace {
35 
36 class WorkerThreadDelegate;
37 
38 }  // namespace
39 
40 // Manages a group of threads which are each associated with one or more
41 // SingleThreadTaskRunners.
42 //
43 // SingleThreadTaskRunners using SingleThreadTaskRunnerThreadMode::SHARED are
44 // backed by shared WorkerThreads for each COM+task environment combination.
45 // These workers are lazily instantiated and then only reclaimed during
46 // JoinForTesting()
47 //
48 // No threads are created (and hence no tasks can run) before Start() is called.
49 //
50 // This class is thread-safe.
51 class BASE_EXPORT PooledSingleThreadTaskRunnerManager final {
52  public:
53   PooledSingleThreadTaskRunnerManager(TrackedRef<TaskTracker> task_tracker,
54                                       DelayedTaskManager* delayed_task_manager);
55   PooledSingleThreadTaskRunnerManager(
56       const PooledSingleThreadTaskRunnerManager&) = delete;
57   PooledSingleThreadTaskRunnerManager& operator=(
58       const PooledSingleThreadTaskRunnerManager&) = delete;
59   ~PooledSingleThreadTaskRunnerManager();
60 
61   // Starts threads for existing SingleThreadTaskRunners and allows threads to
62   // be started when SingleThreadTaskRunners are created in the future.
63   // `io_thread_task_runner` is used to setup FileDescriptorWatcher on worker
64   // threads. `io_thread_task_runner` must refer to a Thread with
65   // MessgaePumpType::IO. If specified, |worker_thread_observer| will be
66   // notified when a worker enters and exits its main function. It must not be
67   // destroyed before JoinForTesting() has returned (must never be destroyed in
68   // production).
69   void Start(scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner,
70              WorkerThreadObserver* worker_thread_observer = nullptr);
71 
72   // Wakes up workers as appropriate for the new CanRunPolicy policy. Must be
73   // called after an update to CanRunPolicy in TaskTracker.
74   void DidUpdateCanRunPolicy();
75 
76   // Creates a SingleThreadTaskRunner which runs tasks with |traits| on a thread
77   // named "ThreadPoolSingleThread[Shared]" +
78   // kEnvironmentParams[GetEnvironmentIndexForTraits(traits)].name_suffix +
79   // index.
80   scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner(
81       const TaskTraits& traits,
82       SingleThreadTaskRunnerThreadMode thread_mode);
83 
84 #if BUILDFLAG(IS_WIN)
85   // Creates a SingleThreadTaskRunner which runs tasks with |traits| on a COM
86   // STA thread named "ThreadPoolSingleThreadCOMSTA[Shared]" +
87   // kEnvironmentParams[GetEnvironmentIndexForTraits(traits)].name_suffix +
88   // index.
89   scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner(
90       const TaskTraits& traits,
91       SingleThreadTaskRunnerThreadMode thread_mode);
92 #endif  // BUILDFLAG(IS_WIN)
93 
94   void JoinForTesting();
95 
96  private:
97   class PooledSingleThreadTaskRunner;
98 
99   enum ContinueOnShutdown {
100     IS_CONTINUE_ON_SHUTDOWN,
101     IS_NOT_CONTINUE_ON_SHUTDOWN,
102     CONTINUE_ON_SHUTDOWN_COUNT,
103   };
104 
105   static ContinueOnShutdown TraitsToContinueOnShutdown(
106       const TaskTraits& traits);
107 
108   template <typename DelegateType>
109   scoped_refptr<PooledSingleThreadTaskRunner> CreateTaskRunnerImpl(
110       const TaskTraits& traits,
111       SingleThreadTaskRunnerThreadMode thread_mode);
112 
113   template <typename DelegateType>
114   std::unique_ptr<WorkerThreadDelegate> CreateWorkerThreadDelegate(
115       const std::string& name,
116       int id,
117       SingleThreadTaskRunnerThreadMode thread_mode);
118 
119   template <typename DelegateType>
120   WorkerThread* CreateAndRegisterWorkerThread(
121       const std::string& name,
122       SingleThreadTaskRunnerThreadMode thread_mode,
123       ThreadType thread_type_hint) EXCLUSIVE_LOCKS_REQUIRED(lock_);
124 
125   template <typename DelegateType>
126   WorkerThread*& GetSharedWorkerThreadForTraits(const TaskTraits& traits);
127 
128   void UnregisterWorkerThread(WorkerThread* worker);
129 
130   void ReleaseSharedWorkerThreads();
131 
132   const TrackedRef<TaskTracker> task_tracker_;
133   const raw_ptr<DelayedTaskManager> delayed_task_manager_;
134 
135   scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner_;
136 
137   // Optional observer notified when a worker enters and exits its main
138   // function. Set in Start() and never modified afterwards.
139   raw_ptr<WorkerThreadObserver> worker_thread_observer_ = nullptr;
140 
141   CheckedLock lock_;
142   std::vector<scoped_refptr<WorkerThread>> workers_ GUARDED_BY(lock_);
143   int next_worker_id_ GUARDED_BY(lock_) = 0;
144 
145   // Workers for SingleThreadTaskRunnerThreadMode::SHARED tasks. It is
146   // important to have separate threads for CONTINUE_ON_SHUTDOWN and non-
147   // CONTINUE_ON_SHUTDOWN to avoid being in a situation where a
148   // CONTINUE_ON_SHUTDOWN task effectively blocks shutdown by preventing a
149   // BLOCK_SHUTDOWN task to be scheduled. https://crbug.com/829786
150   WorkerThread* shared_worker_threads_[ENVIRONMENT_COUNT]
151                                       [CONTINUE_ON_SHUTDOWN_COUNT] GUARDED_BY(
152                                           lock_) = {};
153 #if BUILDFLAG(IS_WIN)
154   WorkerThread* shared_com_worker_threads_
155       [ENVIRONMENT_COUNT][CONTINUE_ON_SHUTDOWN_COUNT] GUARDED_BY(lock_) = {};
156 #endif  // BUILDFLAG(IS_WIN)
157 
158   // Set to true when Start() is called.
159   bool started_ GUARDED_BY(lock_) = false;
160 };
161 
162 }  // namespace internal
163 }  // namespace base
164 
165 #endif  // BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_
166