blob: 7d8b9b434c27660711933419cbcb991c12497a23 [file] [log] [blame]
Gabriel Charette43de5c42020-01-27 22:44:451// Copyright 2019 The Chromium Authors. All rights reserved.
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
Gabriel Charette43de5c42020-01-27 22:44:4511#include "base/base_export.h"
12#include "base/bind.h"
13#include "base/callback.h"
14#include "base/callback_helpers.h"
15#include "base/location.h"
16#include "base/memory/scoped_refptr.h"
17#include "base/post_task_and_reply_with_result_internal.h"
18#include "base/sequenced_task_runner.h"
19#include "base/single_thread_task_runner.h"
20#include "base/task/single_thread_task_runner_thread_mode.h"
Javier Flores0d0d0a62021-03-24 12:07:0621#include "base/task/task_traits.h"
Gabriel Charette43de5c42020-01-27 22:44:4522#include "base/task_runner.h"
23#include "base/time/time.h"
Javier Flores0d0d0a62021-03-24 12:07:0624#include "base/updateable_sequenced_task_runner.h"
Gabriel Charette43de5c42020-01-27 22:44:4525#include "build/build_config.h"
26
27namespace 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.
68class BASE_EXPORT ThreadPool {
69 public:
Javier Flores0d0d0a62021-03-24 12:07:0670 // base::ThreadPool is a static API. See base::ThreadPoolInstance for the
71 // actual instance.
72 ThreadPool() = delete;
Gabriel Charette43de5c42020-01-27 22:44:4573
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,
104 typename = EnableIfIsBaseCallback<CallbackType>>
105 static bool PostTaskAndReplyWithResult(
106 const Location& from_here,
107 CallbackType<TaskReturnType()> task,
108 CallbackType<void(ReplyArgType)> reply) {
David Van Clevebb6112e2020-05-05 15:58:52109 return ThreadPool::PostTaskAndReplyWithResult(
110 from_here, {}, std::move(task), std::move(reply));
Gabriel Charette43de5c42020-01-27 22:44:45111 }
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 // SequencedTaskRunnerHandle::IsSet().
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 SequencedTaskRunnerHandle::IsSet().
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,
154 typename = EnableIfIsBaseCallback<CallbackType>>
Gabriel Charettebcc2327a22020-01-29 03:33:14155 static bool PostTaskAndReplyWithResult(
156 const Location& from_here,
157 const TaskTraits& traits,
158 CallbackType<TaskReturnType()> task,
159 CallbackType<void(ReplyArgType)> reply) {
Gabriel Charette43de5c42020-01-27 22:44:45160 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 defined(OS_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 // defined(OS_WIN)
226};
227
228} // namespace base
229
230#endif // BASE_TASK_THREAD_POOL_H_