xref: /aosp_15_r20/external/cronet/base/task/thread_pool.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 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_H_
6 #define BASE_TASK_THREAD_POOL_H_
7 
8 #include <memory>
9 #include <utility>
10 
11 #include "base/base_export.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/functional/callback_helpers.h"
15 #include "base/location.h"
16 #include "base/memory/scoped_refptr.h"
17 #include "base/task/post_task_and_reply_with_result_internal.h"
18 #include "base/task/sequenced_task_runner.h"
19 #include "base/task/single_thread_task_runner.h"
20 #include "base/task/single_thread_task_runner_thread_mode.h"
21 #include "base/task/task_runner.h"
22 #include "base/task/task_traits.h"
23 #include "base/task/updateable_sequenced_task_runner.h"
24 #include "base/time/time.h"
25 #include "build/build_config.h"
26 
27 namespace base {
28 
29 // This is the interface to post tasks to base's thread pool.
30 //
31 // To post a simple one-off task with default traits:
32 //     base::ThreadPool::PostTask(FROM_HERE, base::BindOnce(...));
33 //
34 // To post a high priority one-off task to respond to a user interaction:
35 //     base::ThreadPool::PostTask(
36 //         FROM_HERE,
37 //         {base::TaskPriority::USER_BLOCKING},
38 //         base::BindOnce(...));
39 //
40 // To post tasks that must run in sequence with default traits:
41 //     scoped_refptr<SequencedTaskRunner> task_runner =
42 //         base::ThreadPool::CreateSequencedTaskRunner();
43 //     task_runner->PostTask(FROM_HERE, base::BindOnce(...));
44 //     task_runner->PostTask(FROM_HERE, base::BindOnce(...));
45 //
46 // To post tasks that may block, must run in sequence and can be skipped on
47 // shutdown:
48 //     scoped_refptr<SequencedTaskRunner> task_runner =
49 //         base::ThreadPool::CreateSequencedTaskRunner(
50 //             {MayBlock(), TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
51 //     task_runner->PostTask(FROM_HERE, base::BindOnce(...));
52 //     task_runner->PostTask(FROM_HERE, base::BindOnce(...));
53 //
54 // The default traits apply to tasks that:
55 //     (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()),
56 //     (2) prefer inheriting the current priority to specifying their own, and
57 //     (3) can either block shutdown or be skipped on shutdown
58 //         (implementation is free to choose a fitting default).
59 // Explicit traits must be specified for tasks for which these loose
60 // requirements are not sufficient.
61 //
62 // Prerequisite: A ThreadPoolInstance must have been registered for the current
63 // process via ThreadPoolInstance::Set() before the API below can be invoked.
64 // This is typically done during the initialization phase in each process. If
65 // your code is not running in that phase, you most likely don't have to worry
66 // about this. You will encounter DCHECKs or nullptr dereferences if this is
67 // violated. For tests, use base::test::TaskEnvironment.
68 class BASE_EXPORT ThreadPool {
69  public:
70   // base::ThreadPool is a static API. See base::ThreadPoolInstance for the
71   // actual instance.
72   ThreadPool() = delete;
73 
74   // Equivalent to calling PostTask with default TaskTraits.
75   static bool PostTask(const Location& from_here, OnceClosure task);
76   inline static bool PostTask(OnceClosure task,
77                               const Location& from_here = Location::Current()) {
78     return PostTask(from_here, std::move(task));
79   }
80 
81   // Equivalent to calling PostDelayedTask with default TaskTraits.
82   //
83   // Use PostDelayedTask to specify a BEST_EFFORT priority if the task doesn't
84   // have to run as soon as |delay| expires.
85   static bool PostDelayedTask(const Location& from_here,
86                               OnceClosure task,
87                               TimeDelta delay);
88 
89   // Equivalent to calling PostTaskAndReply with default TaskTraits.
90   static bool PostTaskAndReply(const Location& from_here,
91                                OnceClosure task,
92                                OnceClosure reply);
93 
94   // Equivalent to calling PostTaskAndReplyWithResult with default TaskTraits.
95   //
96   // Though RepeatingCallback is convertible to OnceCallback, we need a
97   // CallbackType template since we can not use template deduction and object
98   // conversion at once on the overload resolution.
99   // TODO(crbug.com/714018): Update all callers of the RepeatingCallback version
100   // to use OnceCallback and remove the CallbackType template.
101   template <template <typename> class CallbackType,
102             typename TaskReturnType,
103             typename ReplyArgType>
requires(IsBaseCallback<CallbackType<void ()>>)104     requires(IsBaseCallback<CallbackType<void()>>)
105   static bool PostTaskAndReplyWithResult(
106       const Location& from_here,
107       CallbackType<TaskReturnType()> task,
108       CallbackType<void(ReplyArgType)> reply) {
109     return ThreadPool::PostTaskAndReplyWithResult(
110         from_here, {}, std::move(task), std::move(reply));
111   }
112 
113   // Posts |task| with specific |traits|. Returns false if the task definitely
114   // won't run because of current shutdown state.
115   static bool PostTask(const Location& from_here,
116                        const TaskTraits& traits,
117                        OnceClosure task);
118 
119   // Posts |task| with specific |traits|. |task| will not run before |delay|
120   // expires. Returns false if the task definitely won't run because of current
121   // shutdown state.
122   //
123   // Specify a BEST_EFFORT priority via |traits| if the task doesn't have to run
124   // as soon as |delay| expires.
125   static bool PostDelayedTask(const Location& from_here,
126                               const TaskTraits& traits,
127                               OnceClosure task,
128                               TimeDelta delay);
129 
130   // Posts |task| with specific |traits| and posts |reply| on the caller's
131   // execution context (i.e. same sequence or thread and same TaskTraits if
132   // applicable) when |task| completes. Returns false if the task definitely
133   // won't run because of current shutdown state. Can only be called when
134   // SequencedTaskRunner::HasCurrentDefault().
135   static bool PostTaskAndReply(const Location& from_here,
136                                const TaskTraits& traits,
137                                OnceClosure task,
138                                OnceClosure reply);
139 
140   // Posts |task| with specific |traits| and posts |reply| with the return value
141   // of |task| as argument on the caller's execution context (i.e. same sequence
142   // or thread and same TaskTraits if applicable) when |task| completes. Returns
143   // false if the task definitely won't run because of current shutdown state.
144   // Can only be called when SequencedTaskRunner::HasCurrentDefault().
145   //
146   // Though RepeatingCallback is convertible to OnceCallback, we need a
147   // CallbackType template since we can not use template deduction and object
148   // conversion at once on the overload resolution.
149   // TODO(crbug.com/714018): Update all callers of the RepeatingCallback version
150   // to use OnceCallback and remove the CallbackType template.
151   template <template <typename> class CallbackType,
152             typename TaskReturnType,
153             typename ReplyArgType>
requires(IsBaseCallback<CallbackType<void ()>>)154     requires(IsBaseCallback<CallbackType<void()>>)
155   static bool PostTaskAndReplyWithResult(
156       const Location& from_here,
157       const TaskTraits& traits,
158       CallbackType<TaskReturnType()> task,
159       CallbackType<void(ReplyArgType)> reply) {
160     auto* result = new std::unique_ptr<TaskReturnType>();
161     return PostTaskAndReply(
162         from_here, traits,
163         BindOnce(&internal::ReturnAsParamAdapter<TaskReturnType>,
164                  std::move(task), result),
165         BindOnce(&internal::ReplyAdapter<TaskReturnType, ReplyArgType>,
166                  std::move(reply), Owned(result)));
167   }
168 
169   // Returns a TaskRunner whose PostTask invocations result in scheduling tasks
170   // using |traits|. Tasks may run in any order and in parallel.
171   static scoped_refptr<TaskRunner> CreateTaskRunner(const TaskTraits& traits);
172 
173   // Returns a SequencedTaskRunner whose PostTask invocations result in
174   // scheduling tasks using |traits|. Tasks run one at a time in posting order.
175   static scoped_refptr<SequencedTaskRunner> CreateSequencedTaskRunner(
176       const TaskTraits& traits);
177 
178   // Returns a task runner whose PostTask invocations result in scheduling tasks
179   // using |traits|. The priority in |traits| can be updated at any time via
180   // UpdateableSequencedTaskRunner::UpdatePriority(). An update affects all
181   // tasks posted to the task runner that aren't running yet. Tasks run one at a
182   // time in posting order.
183   //
184   // |traits| requirements:
185   // - base::ThreadPolicy must be specified if the priority of the task runner
186   //   will ever be increased from BEST_EFFORT.
187   static scoped_refptr<UpdateableSequencedTaskRunner>
188   CreateUpdateableSequencedTaskRunner(const TaskTraits& traits);
189 
190   // Returns a SingleThreadTaskRunner whose PostTask invocations result in
191   // scheduling tasks using |traits| on a thread determined by |thread_mode|.
192   // See base/task/single_thread_task_runner_thread_mode.h for |thread_mode|
193   // details. If |traits| identifies an existing thread,
194   // SingleThreadTaskRunnerThreadMode::SHARED must be used. Tasks run on a
195   // single thread in posting order.
196   //
197   // If all you need is to make sure that tasks don't run concurrently (e.g.
198   // because they access a data structure which is not thread-safe), use
199   // CreateSequencedTaskRunner(). Only use this if you rely on a thread-affine
200   // API (it might be safer to assume thread-affinity when dealing with
201   // under-documented third-party APIs, e.g. other OS') or share data across
202   // tasks using thread-local storage.
203   static scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunner(
204       const TaskTraits& traits,
205       SingleThreadTaskRunnerThreadMode thread_mode =
206           SingleThreadTaskRunnerThreadMode::SHARED);
207 
208 #if BUILDFLAG(IS_WIN)
209   // Returns a SingleThreadTaskRunner whose PostTask invocations result in
210   // scheduling tasks using |traits| in a COM Single-Threaded Apartment on a
211   // thread determined by |thread_mode|. See
212   // base/task/single_thread_task_runner_thread_mode.h for |thread_mode|
213   // details. If |traits| identifies an existing thread,
214   // SingleThreadTaskRunnerThreadMode::SHARED must be used. Tasks run in the
215   // same Single-Threaded Apartment in posting order for the returned
216   // SingleThreadTaskRunner. There is not necessarily a one-to-one
217   // correspondence between SingleThreadTaskRunners and Single-Threaded
218   // Apartments. The implementation is free to share apartments or create new
219   // apartments as necessary. In either case, care should be taken to make sure
220   // COM pointers are not smuggled across apartments.
221   static scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner(
222       const TaskTraits& traits,
223       SingleThreadTaskRunnerThreadMode thread_mode =
224           SingleThreadTaskRunnerThreadMode::SHARED);
225 #endif  // BUILDFLAG(IS_WIN)
226 };
227 
228 }  // namespace base
229 
230 #endif  // BASE_TASK_THREAD_POOL_H_
231