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