xref: /aosp_15_r20/external/cronet/base/task/thread_pool/pooled_single_thread_task_runner_manager.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 WorkerThreadWaitableEvent;
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   WorkerThreadWaitableEvent* 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   WorkerThreadWaitableEvent*& GetSharedWorkerThreadForTraits(
127       const TaskTraits& traits);
128 
129   void UnregisterWorkerThread(WorkerThreadWaitableEvent* worker);
130 
131   void ReleaseSharedWorkerThreads();
132 
133   const TrackedRef<TaskTracker> task_tracker_;
134   const raw_ptr<DelayedTaskManager> delayed_task_manager_;
135 
136   scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner_;
137 
138   // Optional observer notified when a worker enters and exits its main
139   // function. Set in Start() and never modified afterwards.
140   raw_ptr<WorkerThreadObserver> worker_thread_observer_ = nullptr;
141 
142   CheckedLock lock_;
143   std::vector<scoped_refptr<WorkerThreadWaitableEvent>> workers_
144       GUARDED_BY(lock_);
145   int next_worker_id_ GUARDED_BY(lock_) = 0;
146 
147   // Workers for SingleThreadTaskRunnerThreadMode::SHARED tasks. It is
148   // important to have separate threads for CONTINUE_ON_SHUTDOWN and non-
149   // CONTINUE_ON_SHUTDOWN to avoid being in a situation where a
150   // CONTINUE_ON_SHUTDOWN task effectively blocks shutdown by preventing a
151   // BLOCK_SHUTDOWN task to be scheduled. https://crbug.com/829786
152   WorkerThreadWaitableEvent*
153       shared_worker_threads_[ENVIRONMENT_COUNT]
154                             [CONTINUE_ON_SHUTDOWN_COUNT] GUARDED_BY(lock_) = {};
155 #if BUILDFLAG(IS_WIN)
156   WorkerThreadWaitableEvent* shared_com_worker_threads_
157       [ENVIRONMENT_COUNT][CONTINUE_ON_SHUTDOWN_COUNT] GUARDED_BY(lock_) = {};
158 #endif  // BUILDFLAG(IS_WIN)
159 
160   // Set to true when Start() is called.
161   bool started_ GUARDED_BY(lock_) = false;
162 };
163 
164 }  // namespace internal
165 }  // namespace base
166 
167 #endif  // BASE_TASK_THREAD_POOL_POOLED_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_
168