xref: /aosp_15_r20/external/cronet/base/task/sequenced_task_runner.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TASK_SEQUENCED_TASK_RUNNER_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_TASK_SEQUENCED_TASK_RUNNER_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/task/delay_policy.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/task/delayed_task_handle.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner_helpers.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/task/task_runner.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/types/pass_key.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker namespace blink {
21*6777b538SAndroid Build Coastguard Worker class LowPrecisionTimer;
22*6777b538SAndroid Build Coastguard Worker class TimerBase;
23*6777b538SAndroid Build Coastguard Worker class TimerBasedTickProvider;
24*6777b538SAndroid Build Coastguard Worker class WebRtcTaskQueue;
25*6777b538SAndroid Build Coastguard Worker }
26*6777b538SAndroid Build Coastguard Worker namespace IPC {
27*6777b538SAndroid Build Coastguard Worker class ChannelAssociatedGroupController;
28*6777b538SAndroid Build Coastguard Worker }  // namespace IPC
29*6777b538SAndroid Build Coastguard Worker namespace media {
30*6777b538SAndroid Build Coastguard Worker class AlsaPcmOutputStream;
31*6777b538SAndroid Build Coastguard Worker class AlsaPcmInputStream;
32*6777b538SAndroid Build Coastguard Worker class FakeAudioWorker;
33*6777b538SAndroid Build Coastguard Worker }  // namespace media
34*6777b538SAndroid Build Coastguard Worker namespace webrtc {
35*6777b538SAndroid Build Coastguard Worker class ThreadWrapper;
36*6777b538SAndroid Build Coastguard Worker }  // namespace webrtc
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker namespace base {
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker namespace android {
41*6777b538SAndroid Build Coastguard Worker class PreFreezeBackgroundMemoryTrimmer;
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker namespace internal {
44*6777b538SAndroid Build Coastguard Worker class DelayTimerBase;
45*6777b538SAndroid Build Coastguard Worker class DelayedTaskManager;
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker class DeadlineTimer;
48*6777b538SAndroid Build Coastguard Worker class MetronomeTimer;
49*6777b538SAndroid Build Coastguard Worker class SingleThreadTaskRunner;
50*6777b538SAndroid Build Coastguard Worker class TimeDelta;
51*6777b538SAndroid Build Coastguard Worker class TimeTicks;
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker namespace subtle {
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker // Restricts access to PostCancelableDelayedTask*() to authorized callers.
56*6777b538SAndroid Build Coastguard Worker class PostDelayedTaskPassKey {
57*6777b538SAndroid Build Coastguard Worker  private:
58*6777b538SAndroid Build Coastguard Worker   // Avoid =default to disallow creation by uniform initialization.
PostDelayedTaskPassKey()59*6777b538SAndroid Build Coastguard Worker   PostDelayedTaskPassKey() {}
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   friend class base::internal::DelayTimerBase;
62*6777b538SAndroid Build Coastguard Worker   friend class base::internal::DelayedTaskManager;
63*6777b538SAndroid Build Coastguard Worker   friend class base::DeadlineTimer;
64*6777b538SAndroid Build Coastguard Worker   friend class base::MetronomeTimer;
65*6777b538SAndroid Build Coastguard Worker   friend class blink::LowPrecisionTimer;
66*6777b538SAndroid Build Coastguard Worker   friend class blink::TimerBase;
67*6777b538SAndroid Build Coastguard Worker   friend class blink::TimerBasedTickProvider;
68*6777b538SAndroid Build Coastguard Worker   friend class blink::WebRtcTaskQueue;
69*6777b538SAndroid Build Coastguard Worker   friend class PostDelayedTaskPassKeyForTesting;
70*6777b538SAndroid Build Coastguard Worker   friend class webrtc::ThreadWrapper;
71*6777b538SAndroid Build Coastguard Worker   friend class media::AlsaPcmOutputStream;
72*6777b538SAndroid Build Coastguard Worker   friend class media::AlsaPcmInputStream;
73*6777b538SAndroid Build Coastguard Worker   friend class media::FakeAudioWorker;
74*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
75*6777b538SAndroid Build Coastguard Worker   friend class base::android::PreFreezeBackgroundMemoryTrimmer;
76*6777b538SAndroid Build Coastguard Worker #endif
77*6777b538SAndroid Build Coastguard Worker };
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker // Restricts access to RunOrPostTask() to authorized callers.
80*6777b538SAndroid Build Coastguard Worker class RunOrPostTaskPassKey {
81*6777b538SAndroid Build Coastguard Worker  private:
82*6777b538SAndroid Build Coastguard Worker   // Avoid =default to disallow creation by uniform initialization.
RunOrPostTaskPassKey()83*6777b538SAndroid Build Coastguard Worker   RunOrPostTaskPassKey() {}
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker   friend class IPC::ChannelAssociatedGroupController;
86*6777b538SAndroid Build Coastguard Worker   friend class RunOrPostTaskPassKeyForTesting;
87*6777b538SAndroid Build Coastguard Worker };
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker class PostDelayedTaskPassKeyForTesting : public PostDelayedTaskPassKey {};
90*6777b538SAndroid Build Coastguard Worker class RunOrPostTaskPassKeyForTesting : public RunOrPostTaskPassKey {};
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker }  // namespace subtle
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker // A SequencedTaskRunner is a subclass of TaskRunner that provides
95*6777b538SAndroid Build Coastguard Worker // additional guarantees on the order that tasks are started, as well
96*6777b538SAndroid Build Coastguard Worker // as guarantees on when tasks are in sequence, i.e. one task finishes
97*6777b538SAndroid Build Coastguard Worker // before the other one starts.
98*6777b538SAndroid Build Coastguard Worker //
99*6777b538SAndroid Build Coastguard Worker // Summary
100*6777b538SAndroid Build Coastguard Worker // -------
101*6777b538SAndroid Build Coastguard Worker // Non-nested tasks with the same delay will run one by one in FIFO
102*6777b538SAndroid Build Coastguard Worker // order.
103*6777b538SAndroid Build Coastguard Worker //
104*6777b538SAndroid Build Coastguard Worker // Detailed guarantees
105*6777b538SAndroid Build Coastguard Worker // -------------------
106*6777b538SAndroid Build Coastguard Worker //
107*6777b538SAndroid Build Coastguard Worker // SequencedTaskRunner also adds additional methods for posting
108*6777b538SAndroid Build Coastguard Worker // non-nestable tasks.  In general, an implementation of TaskRunner
109*6777b538SAndroid Build Coastguard Worker // may expose task-running methods which are themselves callable from
110*6777b538SAndroid Build Coastguard Worker // within tasks.  A non-nestable task is one that is guaranteed to not
111*6777b538SAndroid Build Coastguard Worker // be run from within an already-running task.  Conversely, a nestable
112*6777b538SAndroid Build Coastguard Worker // task (the default) is a task that can be run from within an
113*6777b538SAndroid Build Coastguard Worker // already-running task.
114*6777b538SAndroid Build Coastguard Worker //
115*6777b538SAndroid Build Coastguard Worker // The guarantees of SequencedTaskRunner are as follows:
116*6777b538SAndroid Build Coastguard Worker //
117*6777b538SAndroid Build Coastguard Worker //   - Given two tasks T2 and T1, T2 will start after T1 starts if:
118*6777b538SAndroid Build Coastguard Worker //
119*6777b538SAndroid Build Coastguard Worker //       * T2 is posted after T1; and
120*6777b538SAndroid Build Coastguard Worker //       * T2 has equal or higher delay than T1; and
121*6777b538SAndroid Build Coastguard Worker //       * T2 is non-nestable or T1 is nestable.
122*6777b538SAndroid Build Coastguard Worker //
123*6777b538SAndroid Build Coastguard Worker //   - If T2 will start after T1 starts by the above guarantee, then
124*6777b538SAndroid Build Coastguard Worker //     T2 will start after T1 finishes and is destroyed if:
125*6777b538SAndroid Build Coastguard Worker //
126*6777b538SAndroid Build Coastguard Worker //       * T2 is non-nestable, or
127*6777b538SAndroid Build Coastguard Worker //       * T1 doesn't call any task-running methods.
128*6777b538SAndroid Build Coastguard Worker //
129*6777b538SAndroid Build Coastguard Worker //   - If T2 will start after T1 finishes by the above guarantee, then
130*6777b538SAndroid Build Coastguard Worker //     all memory changes in T1 and T1's destruction will be visible
131*6777b538SAndroid Build Coastguard Worker //     to T2.
132*6777b538SAndroid Build Coastguard Worker //
133*6777b538SAndroid Build Coastguard Worker //   - If T2 runs nested within T1 via a call to the task-running
134*6777b538SAndroid Build Coastguard Worker //     method M, then all memory changes in T1 up to the call to M
135*6777b538SAndroid Build Coastguard Worker //     will be visible to T2, and all memory changes in T2 will be
136*6777b538SAndroid Build Coastguard Worker //     visible to T1 from the return from M.
137*6777b538SAndroid Build Coastguard Worker //
138*6777b538SAndroid Build Coastguard Worker // Note that SequencedTaskRunner does not guarantee that tasks are run
139*6777b538SAndroid Build Coastguard Worker // on a single dedicated thread, although the above guarantees provide
140*6777b538SAndroid Build Coastguard Worker // most (but not all) of the same guarantees.  If you do need to
141*6777b538SAndroid Build Coastguard Worker // guarantee that tasks are run on a single dedicated thread, see
142*6777b538SAndroid Build Coastguard Worker // SingleThreadTaskRunner (in single_thread_task_runner.h).
143*6777b538SAndroid Build Coastguard Worker //
144*6777b538SAndroid Build Coastguard Worker // Some corollaries to the above guarantees, assuming the tasks in
145*6777b538SAndroid Build Coastguard Worker // question don't call any task-running methods:
146*6777b538SAndroid Build Coastguard Worker //
147*6777b538SAndroid Build Coastguard Worker //   - Tasks posted via PostTask are run in FIFO order.
148*6777b538SAndroid Build Coastguard Worker //
149*6777b538SAndroid Build Coastguard Worker //   - Tasks posted via PostNonNestableTask are run in FIFO order.
150*6777b538SAndroid Build Coastguard Worker //
151*6777b538SAndroid Build Coastguard Worker //   - Tasks posted with the same delay and the same nestable state
152*6777b538SAndroid Build Coastguard Worker //     are run in FIFO order.
153*6777b538SAndroid Build Coastguard Worker //
154*6777b538SAndroid Build Coastguard Worker //   - A list of tasks with the same nestable state posted in order of
155*6777b538SAndroid Build Coastguard Worker //     non-decreasing delay is run in FIFO order.
156*6777b538SAndroid Build Coastguard Worker //
157*6777b538SAndroid Build Coastguard Worker //   - A list of tasks posted in order of non-decreasing delay with at
158*6777b538SAndroid Build Coastguard Worker //     most a single change in nestable state from nestable to
159*6777b538SAndroid Build Coastguard Worker //     non-nestable is run in FIFO order. (This is equivalent to the
160*6777b538SAndroid Build Coastguard Worker //     statement of the first guarantee above.)
161*6777b538SAndroid Build Coastguard Worker //
162*6777b538SAndroid Build Coastguard Worker // Some theoretical implementations of SequencedTaskRunner:
163*6777b538SAndroid Build Coastguard Worker //
164*6777b538SAndroid Build Coastguard Worker //   - A SequencedTaskRunner that wraps a regular TaskRunner but makes
165*6777b538SAndroid Build Coastguard Worker //     sure that only one task at a time is posted to the TaskRunner,
166*6777b538SAndroid Build Coastguard Worker //     with appropriate memory barriers in between tasks.
167*6777b538SAndroid Build Coastguard Worker //
168*6777b538SAndroid Build Coastguard Worker //   - A SequencedTaskRunner that, for each task, spawns a joinable
169*6777b538SAndroid Build Coastguard Worker //     thread to run that task and immediately quit, and then
170*6777b538SAndroid Build Coastguard Worker //     immediately joins that thread.
171*6777b538SAndroid Build Coastguard Worker //
172*6777b538SAndroid Build Coastguard Worker //   - A SequencedTaskRunner that stores the list of posted tasks and
173*6777b538SAndroid Build Coastguard Worker //     has a method Run() that runs each runnable task in FIFO order
174*6777b538SAndroid Build Coastguard Worker //     that can be called from any thread, but only if another
175*6777b538SAndroid Build Coastguard Worker //     (non-nested) Run() call isn't already happening.
176*6777b538SAndroid Build Coastguard Worker //
177*6777b538SAndroid Build Coastguard Worker // SequencedTaskRunner::GetCurrentDefault() can be used while running
178*6777b538SAndroid Build Coastguard Worker // a task to retrieve the default SequencedTaskRunner for the current
179*6777b538SAndroid Build Coastguard Worker // sequence.
180*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT SequencedTaskRunner : public TaskRunner {
181*6777b538SAndroid Build Coastguard Worker  public:
182*6777b538SAndroid Build Coastguard Worker   // The two PostNonNestable*Task methods below are like their
183*6777b538SAndroid Build Coastguard Worker   // nestable equivalents in TaskRunner, but they guarantee that the
184*6777b538SAndroid Build Coastguard Worker   // posted task will not run nested within an already-running task.
185*6777b538SAndroid Build Coastguard Worker   //
186*6777b538SAndroid Build Coastguard Worker   // A simple corollary is that posting a task as non-nestable can
187*6777b538SAndroid Build Coastguard Worker   // only delay when the task gets run.  That is, posting a task as
188*6777b538SAndroid Build Coastguard Worker   // non-nestable may not affect when the task gets run, or it could
189*6777b538SAndroid Build Coastguard Worker   // make it run later than it normally would, but it won't make it
190*6777b538SAndroid Build Coastguard Worker   // run earlier than it normally would.
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // TODO(akalin): Get rid of the boolean return value for the methods
193*6777b538SAndroid Build Coastguard Worker   // below.
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker   bool PostNonNestableTask(const Location& from_here, OnceClosure task);
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker   virtual bool PostNonNestableDelayedTask(const Location& from_here,
198*6777b538SAndroid Build Coastguard Worker                                           OnceClosure task,
199*6777b538SAndroid Build Coastguard Worker                                           base::TimeDelta delay) = 0;
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker   // Posts the given |task| to be run only after |delay| has passed. Returns a
202*6777b538SAndroid Build Coastguard Worker   // handle that can be used to cancel the task. This should not be used
203*6777b538SAndroid Build Coastguard Worker   // directly. Consider using higher level timer primitives in
204*6777b538SAndroid Build Coastguard Worker   // base/timer/timer.h.
205*6777b538SAndroid Build Coastguard Worker   //
206*6777b538SAndroid Build Coastguard Worker   // The handle is only guaranteed valid while the task is pending execution.
207*6777b538SAndroid Build Coastguard Worker   // This means that it may be invalid if the posting failed, and will be
208*6777b538SAndroid Build Coastguard Worker   // invalid while the task is executing. Calling CancelTask() on an invalid
209*6777b538SAndroid Build Coastguard Worker   // handle is a no-op.
210*6777b538SAndroid Build Coastguard Worker   //
211*6777b538SAndroid Build Coastguard Worker   // This method and the handle it returns are not thread-safe and can only be
212*6777b538SAndroid Build Coastguard Worker   // used from the sequence this task runner runs its tasks on.
213*6777b538SAndroid Build Coastguard Worker   virtual DelayedTaskHandle PostCancelableDelayedTask(
214*6777b538SAndroid Build Coastguard Worker       subtle::PostDelayedTaskPassKey,
215*6777b538SAndroid Build Coastguard Worker       const Location& from_here,
216*6777b538SAndroid Build Coastguard Worker       OnceClosure task,
217*6777b538SAndroid Build Coastguard Worker       TimeDelta delay);
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker   // Posts the given |task| to be run at |delayed_run_time| (or immediately if
220*6777b538SAndroid Build Coastguard Worker   // in the past), following |delay_policy|. Returns a handle that can be used
221*6777b538SAndroid Build Coastguard Worker   // to cancel the task. This should not be used directly. Consider using higher
222*6777b538SAndroid Build Coastguard Worker   // level timer primitives in base/timer/timer.h.
223*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] virtual DelayedTaskHandle PostCancelableDelayedTaskAt(
224*6777b538SAndroid Build Coastguard Worker       subtle::PostDelayedTaskPassKey,
225*6777b538SAndroid Build Coastguard Worker       const Location& from_here,
226*6777b538SAndroid Build Coastguard Worker       OnceClosure task,
227*6777b538SAndroid Build Coastguard Worker       TimeTicks delayed_run_time,
228*6777b538SAndroid Build Coastguard Worker       subtle::DelayPolicy delay_policy);
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker   // Posts the given |task| to be run at |delayed_run_time| (or immediately if
231*6777b538SAndroid Build Coastguard Worker   // in the past), following |delay_policy|. This is used by the default
232*6777b538SAndroid Build Coastguard Worker   // implementation of PostCancelableDelayedTaskAt(). The default behavior
233*6777b538SAndroid Build Coastguard Worker   // subtracts TimeTicks::Now() from |delayed_run_time| to get a delay. See
234*6777b538SAndroid Build Coastguard Worker   // base::Timer to post precise/repeating timeouts.
235*6777b538SAndroid Build Coastguard Worker   // TODO(1153139): Make pure virtual once all SequencedTaskRunners implement
236*6777b538SAndroid Build Coastguard Worker   // this.
237*6777b538SAndroid Build Coastguard Worker   virtual bool PostDelayedTaskAt(subtle::PostDelayedTaskPassKey,
238*6777b538SAndroid Build Coastguard Worker                                  const Location& from_here,
239*6777b538SAndroid Build Coastguard Worker                                  OnceClosure task,
240*6777b538SAndroid Build Coastguard Worker                                  TimeTicks delayed_run_time,
241*6777b538SAndroid Build Coastguard Worker                                  subtle::DelayPolicy delay_policy);
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker   // May run `task` synchronously if no work that has ordering or mutual
244*6777b538SAndroid Build Coastguard Worker   // exclusion expectations with tasks from this `SequencedTaskRunner` is
245*6777b538SAndroid Build Coastguard Worker   // pending or running (if such work arrives after `task` starts running
246*6777b538SAndroid Build Coastguard Worker   // synchronously, it waits until `task` finishes). Otherwise, behaves like
247*6777b538SAndroid Build Coastguard Worker   // `PostTask`. Since `task` may run synchronously, it is generally not
248*6777b538SAndroid Build Coastguard Worker   // appropriate to invoke this if `task` may take a long time to run.
249*6777b538SAndroid Build Coastguard Worker   //
250*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/1503967): This API is still in development. It doesn't yet
251*6777b538SAndroid Build Coastguard Worker   // support SequenceLocalStorage.
252*6777b538SAndroid Build Coastguard Worker   virtual bool RunOrPostTask(subtle::RunOrPostTaskPassKey,
253*6777b538SAndroid Build Coastguard Worker                              const Location& from_here,
254*6777b538SAndroid Build Coastguard Worker                              OnceClosure task);
255*6777b538SAndroid Build Coastguard Worker 
256*6777b538SAndroid Build Coastguard Worker   // Submits a non-nestable task to delete the given object.  Returns
257*6777b538SAndroid Build Coastguard Worker   // true if the object may be deleted at some point in the future,
258*6777b538SAndroid Build Coastguard Worker   // and false if the object definitely will not be deleted.
259*6777b538SAndroid Build Coastguard Worker   //
260*6777b538SAndroid Build Coastguard Worker   // By default, this leaks `object` if the deleter task doesn't run, e.g. if
261*6777b538SAndroid Build Coastguard Worker   // the underlying task queue is shut down first. Subclasses can override this
262*6777b538SAndroid Build Coastguard Worker   // behavior by specializing `DeleteOrReleaseSoonInternal()`.
263*6777b538SAndroid Build Coastguard Worker   template <class T>
DeleteSoon(const Location & from_here,const T * object)264*6777b538SAndroid Build Coastguard Worker   bool DeleteSoon(const Location& from_here, const T* object) {
265*6777b538SAndroid Build Coastguard Worker     return DeleteOrReleaseSoonInternal(from_here, &DeleteHelper<T>::DoDelete,
266*6777b538SAndroid Build Coastguard Worker                                        object);
267*6777b538SAndroid Build Coastguard Worker   }
268*6777b538SAndroid Build Coastguard Worker 
269*6777b538SAndroid Build Coastguard Worker   template <class T>
DeleteSoon(const Location & from_here,std::unique_ptr<T> object)270*6777b538SAndroid Build Coastguard Worker   bool DeleteSoon(const Location& from_here, std::unique_ptr<T> object) {
271*6777b538SAndroid Build Coastguard Worker     return DeleteOrReleaseSoonInternal(
272*6777b538SAndroid Build Coastguard Worker         from_here, &DeleteUniquePtrHelper<T>::DoDelete, object.release());
273*6777b538SAndroid Build Coastguard Worker   }
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   // Submits a non-nestable task to release the given object.
276*6777b538SAndroid Build Coastguard Worker   //
277*6777b538SAndroid Build Coastguard Worker   // By default, this leaks `object` if the releaser task doesn't run, e.g. if
278*6777b538SAndroid Build Coastguard Worker   // the underlying task queue is shut down first. Subclasses can override this
279*6777b538SAndroid Build Coastguard Worker   // behavior by specializing `DeleteOrReleaseSoonInternal()`.
280*6777b538SAndroid Build Coastguard Worker   //
281*6777b538SAndroid Build Coastguard Worker   // ReleaseSoon makes sure that the object it the scoped_refptr points to gets
282*6777b538SAndroid Build Coastguard Worker   // properly released on the correct thread.
283*6777b538SAndroid Build Coastguard Worker   // We apply ReleaseSoon to the rvalue as the side-effects can be unclear to
284*6777b538SAndroid Build Coastguard Worker   // the caller if an lvalue is used. That being so, the scoped_refptr should
285*6777b538SAndroid Build Coastguard Worker   // always be std::move'd.
286*6777b538SAndroid Build Coastguard Worker   // Example use:
287*6777b538SAndroid Build Coastguard Worker   //
288*6777b538SAndroid Build Coastguard Worker   // scoped_refptr<T> foo_scoped_refptr;
289*6777b538SAndroid Build Coastguard Worker   // ...
290*6777b538SAndroid Build Coastguard Worker   // task_runner->ReleaseSoon(std::move(foo_scoped_refptr));
291*6777b538SAndroid Build Coastguard Worker   template <class T>
ReleaseSoon(const Location & from_here,scoped_refptr<T> && object)292*6777b538SAndroid Build Coastguard Worker   void ReleaseSoon(const Location& from_here, scoped_refptr<T>&& object) {
293*6777b538SAndroid Build Coastguard Worker     if (!object)
294*6777b538SAndroid Build Coastguard Worker       return;
295*6777b538SAndroid Build Coastguard Worker 
296*6777b538SAndroid Build Coastguard Worker     DeleteOrReleaseSoonInternal(from_here, &ReleaseHelper<T>::DoRelease,
297*6777b538SAndroid Build Coastguard Worker                                 object.release());
298*6777b538SAndroid Build Coastguard Worker   }
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker   // Returns true iff tasks posted to this TaskRunner are sequenced
301*6777b538SAndroid Build Coastguard Worker   // with this call.
302*6777b538SAndroid Build Coastguard Worker   //
303*6777b538SAndroid Build Coastguard Worker   // In particular:
304*6777b538SAndroid Build Coastguard Worker   // - Returns true if this is a SequencedTaskRunner to which the
305*6777b538SAndroid Build Coastguard Worker   //   current task was posted.
306*6777b538SAndroid Build Coastguard Worker   // - Returns true if this is a SequencedTaskRunner bound to the
307*6777b538SAndroid Build Coastguard Worker   //   same sequence as the SequencedTaskRunner to which the current
308*6777b538SAndroid Build Coastguard Worker   //   task was posted.
309*6777b538SAndroid Build Coastguard Worker   // - Returns true if this is a SingleThreadTaskRunner bound to
310*6777b538SAndroid Build Coastguard Worker   //   the current thread.
311*6777b538SAndroid Build Coastguard Worker   virtual bool RunsTasksInCurrentSequence() const = 0;
312*6777b538SAndroid Build Coastguard Worker 
313*6777b538SAndroid Build Coastguard Worker   // Returns the default SequencedTaskRunner for the current task. It
314*6777b538SAndroid Build Coastguard Worker   // should only be called if HasCurrentDefault() returns true (see the comment
315*6777b538SAndroid Build Coastguard Worker   // there for the requirements).
316*6777b538SAndroid Build Coastguard Worker   //
317*6777b538SAndroid Build Coastguard Worker   // It is "default" in the sense that if the current sequence multiplexes
318*6777b538SAndroid Build Coastguard Worker   // multiple task queues (e.g. BrowserThread::UI), this will return the default
319*6777b538SAndroid Build Coastguard Worker   // task queue. A caller that wants a specific task queue should obtain it
320*6777b538SAndroid Build Coastguard Worker   // directly instead of going through this API.
321*6777b538SAndroid Build Coastguard Worker   //
322*6777b538SAndroid Build Coastguard Worker   // See
323*6777b538SAndroid Build Coastguard Worker   // https://chromium.googlesource.com/chromium/src/+/main/docs/threading_and_tasks.md#Posting-to-the-Current-Virtual_Thread
324*6777b538SAndroid Build Coastguard Worker   // for details
325*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] static const scoped_refptr<SequencedTaskRunner>&
326*6777b538SAndroid Build Coastguard Worker   GetCurrentDefault();
327*6777b538SAndroid Build Coastguard Worker 
328*6777b538SAndroid Build Coastguard Worker   // Returns true if one of the following conditions is fulfilled:
329*6777b538SAndroid Build Coastguard Worker   // a) A SequencedTaskRunner has been assigned to the current thread by
330*6777b538SAndroid Build Coastguard Worker   //    instantiating a SequencedTaskRunner::CurrentDefaultHandle.
331*6777b538SAndroid Build Coastguard Worker   // b) The current thread has a SingleThreadTaskRunner::CurrentDefaultHandle
332*6777b538SAndroid Build Coastguard Worker   //    (which includes any thread that runs a MessagePump).
333*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] static bool HasCurrentDefault();
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker   class BASE_EXPORT CurrentDefaultHandle {
336*6777b538SAndroid Build Coastguard Worker    public:
337*6777b538SAndroid Build Coastguard Worker     // Sets the value returned by `SequencedTaskRunner::GetCurrentDefault()` to
338*6777b538SAndroid Build Coastguard Worker     // `task_runner` within its scope. `task_runner` must belong to the current
339*6777b538SAndroid Build Coastguard Worker     // sequence. There must not already be a current default
340*6777b538SAndroid Build Coastguard Worker     // `SequencedTaskRunner` on this thread.
341*6777b538SAndroid Build Coastguard Worker     explicit CurrentDefaultHandle(
342*6777b538SAndroid Build Coastguard Worker         scoped_refptr<SequencedTaskRunner> task_runner);
343*6777b538SAndroid Build Coastguard Worker 
344*6777b538SAndroid Build Coastguard Worker     CurrentDefaultHandle(const CurrentDefaultHandle&) = delete;
345*6777b538SAndroid Build Coastguard Worker     CurrentDefaultHandle& operator=(const CurrentDefaultHandle&) = delete;
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker     ~CurrentDefaultHandle();
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker    private:
350*6777b538SAndroid Build Coastguard Worker     friend class SequencedTaskRunner;
351*6777b538SAndroid Build Coastguard Worker 
352*6777b538SAndroid Build Coastguard Worker     // Overriding an existing current default SingleThreadTaskRunner should only
353*6777b538SAndroid Build Coastguard Worker     // be needed under special circumstances. Require them to be enumerated as
354*6777b538SAndroid Build Coastguard Worker     // friends to require //base/OWNERS review. Use
355*6777b538SAndroid Build Coastguard Worker     // SingleThreadTaskRunner::CurrentHandleOverrideForTesting in unit tests to
356*6777b538SAndroid Build Coastguard Worker     // avoid the friend requirement.
357*6777b538SAndroid Build Coastguard Worker     friend class SingleThreadTaskRunner;
358*6777b538SAndroid Build Coastguard Worker     FRIEND_TEST_ALL_PREFIXES(SequencedTaskRunnerCurrentDefaultHandleTest,
359*6777b538SAndroid Build Coastguard Worker                              OverrideWithNull);
360*6777b538SAndroid Build Coastguard Worker     FRIEND_TEST_ALL_PREFIXES(SequencedTaskRunnerCurrentDefaultHandleTest,
361*6777b538SAndroid Build Coastguard Worker                              OverrideWithNonNull);
362*6777b538SAndroid Build Coastguard Worker 
363*6777b538SAndroid Build Coastguard Worker     struct MayAlreadyExist {};
364*6777b538SAndroid Build Coastguard Worker 
365*6777b538SAndroid Build Coastguard Worker     // Same as the public constructor, but there may already be a current
366*6777b538SAndroid Build Coastguard Worker     // default `SequencedTaskRunner` on this thread.
367*6777b538SAndroid Build Coastguard Worker     CurrentDefaultHandle(scoped_refptr<SequencedTaskRunner> task_runner,
368*6777b538SAndroid Build Coastguard Worker                          MayAlreadyExist);
369*6777b538SAndroid Build Coastguard Worker 
370*6777b538SAndroid Build Coastguard Worker     scoped_refptr<SequencedTaskRunner> task_runner_;
371*6777b538SAndroid Build Coastguard Worker     raw_ptr<CurrentDefaultHandle> previous_handle_;
372*6777b538SAndroid Build Coastguard Worker   };
373*6777b538SAndroid Build Coastguard Worker 
374*6777b538SAndroid Build Coastguard Worker  protected:
375*6777b538SAndroid Build Coastguard Worker   ~SequencedTaskRunner() override = default;
376*6777b538SAndroid Build Coastguard Worker 
377*6777b538SAndroid Build Coastguard Worker   virtual bool DeleteOrReleaseSoonInternal(const Location& from_here,
378*6777b538SAndroid Build Coastguard Worker                                            void (*deleter)(const void*),
379*6777b538SAndroid Build Coastguard Worker                                            const void* object);
380*6777b538SAndroid Build Coastguard Worker };
381*6777b538SAndroid Build Coastguard Worker 
382*6777b538SAndroid Build Coastguard Worker // Sample usage with std::unique_ptr :
383*6777b538SAndroid Build Coastguard Worker // std::unique_ptr<Foo, base::OnTaskRunnerDeleter> ptr(
384*6777b538SAndroid Build Coastguard Worker //     new Foo, base::OnTaskRunnerDeleter(my_task_runner));
385*6777b538SAndroid Build Coastguard Worker //
386*6777b538SAndroid Build Coastguard Worker // For RefCounted see base::RefCountedDeleteOnSequence.
387*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT OnTaskRunnerDeleter {
388*6777b538SAndroid Build Coastguard Worker   explicit OnTaskRunnerDeleter(scoped_refptr<SequencedTaskRunner> task_runner);
389*6777b538SAndroid Build Coastguard Worker   ~OnTaskRunnerDeleter();
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   OnTaskRunnerDeleter(OnTaskRunnerDeleter&&);
392*6777b538SAndroid Build Coastguard Worker   OnTaskRunnerDeleter& operator=(OnTaskRunnerDeleter&&);
393*6777b538SAndroid Build Coastguard Worker 
394*6777b538SAndroid Build Coastguard Worker   // For compatibility with std:: deleters.
395*6777b538SAndroid Build Coastguard Worker   template <typename T>
operatorOnTaskRunnerDeleter396*6777b538SAndroid Build Coastguard Worker   void operator()(const T* ptr) {
397*6777b538SAndroid Build Coastguard Worker     if (ptr)
398*6777b538SAndroid Build Coastguard Worker       task_runner_->DeleteSoon(FROM_HERE, ptr);
399*6777b538SAndroid Build Coastguard Worker   }
400*6777b538SAndroid Build Coastguard Worker 
401*6777b538SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner_;
402*6777b538SAndroid Build Coastguard Worker };
403*6777b538SAndroid Build Coastguard Worker 
404*6777b538SAndroid Build Coastguard Worker }  // namespace base
405*6777b538SAndroid Build Coastguard Worker 
406*6777b538SAndroid Build Coastguard Worker #endif  // BASE_TASK_SEQUENCED_TASK_RUNNER_H_
407