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_RUN_LOOP_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_RUN_LOOP_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stack> 9*6777b538SAndroid Build Coastguard Worker #include <utility> 10*6777b538SAndroid Build Coastguard Worker #include <vector> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/containers/stack.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/dcheck_is_on.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/location.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h" 20*6777b538SAndroid Build Coastguard Worker #include "base/observer_list.h" 21*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 22*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_checker.h" 23*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 24*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 25*6777b538SAndroid Build Coastguard Worker 26*6777b538SAndroid Build Coastguard Worker namespace base { 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker namespace test { 29*6777b538SAndroid Build Coastguard Worker class ScopedRunLoopTimeout; 30*6777b538SAndroid Build Coastguard Worker class ScopedDisableRunLoopTimeout; 31*6777b538SAndroid Build Coastguard Worker } // namespace test 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) 34*6777b538SAndroid Build Coastguard Worker class MessagePumpAndroid; 35*6777b538SAndroid Build Coastguard Worker #endif 36*6777b538SAndroid Build Coastguard Worker 37*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_IOS) 38*6777b538SAndroid Build Coastguard Worker class MessagePumpUIApplication; 39*6777b538SAndroid Build Coastguard Worker #endif 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker class SingleThreadTaskRunner; 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker // Helper class to run the RunLoop::Delegate associated with the current thread. 44*6777b538SAndroid Build Coastguard Worker // A RunLoop::Delegate must have been bound to this thread (ref. 45*6777b538SAndroid Build Coastguard Worker // RunLoop::RegisterDelegateForCurrentThread()) prior to using any of RunLoop's 46*6777b538SAndroid Build Coastguard Worker // member and static methods unless explicitly indicated otherwise (e.g. 47*6777b538SAndroid Build Coastguard Worker // IsRunning/IsNestedOnCurrentThread()). RunLoop::Run can only be called once 48*6777b538SAndroid Build Coastguard Worker // per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run 49*6777b538SAndroid Build Coastguard Worker // a nested RunLoop but please avoid nested loops in production code! 50*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT RunLoop { 51*6777b538SAndroid Build Coastguard Worker public: 52*6777b538SAndroid Build Coastguard Worker // The type of RunLoop: a kDefault RunLoop at the top-level (non-nested) will 53*6777b538SAndroid Build Coastguard Worker // process system and application tasks assigned to its Delegate. When nested 54*6777b538SAndroid Build Coastguard Worker // however a kDefault RunLoop will only process system tasks while a 55*6777b538SAndroid Build Coastguard Worker // kNestableTasksAllowed RunLoop will continue to process application tasks 56*6777b538SAndroid Build Coastguard Worker // even if nested. 57*6777b538SAndroid Build Coastguard Worker // 58*6777b538SAndroid Build Coastguard Worker // This is relevant in the case of recursive RunLoops. Some unwanted run loops 59*6777b538SAndroid Build Coastguard Worker // may occur when using common controls or printer functions. By default, 60*6777b538SAndroid Build Coastguard Worker // recursive task processing is disabled. 61*6777b538SAndroid Build Coastguard Worker // 62*6777b538SAndroid Build Coastguard Worker // In general, nestable RunLoops are to be avoided. They are dangerous and 63*6777b538SAndroid Build Coastguard Worker // difficult to get right, so please use with extreme caution. 64*6777b538SAndroid Build Coastguard Worker // 65*6777b538SAndroid Build Coastguard Worker // A specific example where this makes a difference is: 66*6777b538SAndroid Build Coastguard Worker // - The thread is running a RunLoop. 67*6777b538SAndroid Build Coastguard Worker // - It receives a task #1 and executes it. 68*6777b538SAndroid Build Coastguard Worker // - The task #1 implicitly starts a RunLoop, like a MessageBox in the unit 69*6777b538SAndroid Build Coastguard Worker // test. This can also be StartDoc or GetSaveFileName. 70*6777b538SAndroid Build Coastguard Worker // - The thread receives a task #2 before or while in this second RunLoop. 71*6777b538SAndroid Build Coastguard Worker // - With a kNestableTasksAllowed RunLoop, the task #2 will run right away. 72*6777b538SAndroid Build Coastguard Worker // Otherwise, it will get executed right after task #1 completes in the main 73*6777b538SAndroid Build Coastguard Worker // RunLoop. 74*6777b538SAndroid Build Coastguard Worker enum class Type { 75*6777b538SAndroid Build Coastguard Worker kDefault, 76*6777b538SAndroid Build Coastguard Worker kNestableTasksAllowed, 77*6777b538SAndroid Build Coastguard Worker }; 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker explicit RunLoop(Type type = Type::kDefault); 80*6777b538SAndroid Build Coastguard Worker RunLoop(const RunLoop&) = delete; 81*6777b538SAndroid Build Coastguard Worker RunLoop& operator=(const RunLoop&) = delete; 82*6777b538SAndroid Build Coastguard Worker ~RunLoop(); 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker // Run the current RunLoop::Delegate. This blocks until Quit is called 85*6777b538SAndroid Build Coastguard Worker // (directly or by running the RunLoop::QuitClosure). 86*6777b538SAndroid Build Coastguard Worker void Run(const Location& location = Location::Current()); 87*6777b538SAndroid Build Coastguard Worker 88*6777b538SAndroid Build Coastguard Worker // Run the current RunLoop::Delegate until it doesn't find any tasks or 89*6777b538SAndroid Build Coastguard Worker // messages in its queue (it goes idle). 90*6777b538SAndroid Build Coastguard Worker // WARNING #1: This may run long (flakily timeout) and even never return! Do 91*6777b538SAndroid Build Coastguard Worker // not use this when repeating tasks such as animated web pages 92*6777b538SAndroid Build Coastguard Worker // are present. 93*6777b538SAndroid Build Coastguard Worker // WARNING #2: This may return too early! For example, if used to run until an 94*6777b538SAndroid Build Coastguard Worker // incoming event has occurred but that event depends on a task in 95*6777b538SAndroid Build Coastguard Worker // a different queue -- e.g. another TaskRunner or a system event. 96*6777b538SAndroid Build Coastguard Worker // Per the warnings above, this tends to lead to flaky tests; prefer 97*6777b538SAndroid Build Coastguard Worker // QuitClosure()+Run() when at all possible. 98*6777b538SAndroid Build Coastguard Worker void RunUntilIdle(); 99*6777b538SAndroid Build Coastguard Worker running()100*6777b538SAndroid Build Coastguard Worker bool running() const { 101*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 102*6777b538SAndroid Build Coastguard Worker return running_; 103*6777b538SAndroid Build Coastguard Worker } 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker // Quit() transitions this RunLoop to a state where no more tasks will be 106*6777b538SAndroid Build Coastguard Worker // allowed to run at the run-loop-level of this RunLoop. If invoked from the 107*6777b538SAndroid Build Coastguard Worker // owning thread, the effect is immediate; otherwise it is thread-safe but 108*6777b538SAndroid Build Coastguard Worker // asynchronous. When the transition takes effect, the underlying message loop 109*6777b538SAndroid Build Coastguard Worker // quits this run-loop-level if it is topmost (otherwise the desire to quit 110*6777b538SAndroid Build Coastguard Worker // this level is saved until run-levels nested above it are quit). 111*6777b538SAndroid Build Coastguard Worker // 112*6777b538SAndroid Build Coastguard Worker // QuitWhenIdle() results in this RunLoop returning true from 113*6777b538SAndroid Build Coastguard Worker // ShouldQuitWhenIdle() at this run-level (the delegate decides when "idle" is 114*6777b538SAndroid Build Coastguard Worker // reached). This is also thread-safe. 115*6777b538SAndroid Build Coastguard Worker // 116*6777b538SAndroid Build Coastguard Worker // There can be other nested RunLoops servicing the same task queue. As 117*6777b538SAndroid Build Coastguard Worker // mentioned above, quitting one RunLoop has no bearing on the others. Hence, 118*6777b538SAndroid Build Coastguard Worker // you may never assume that a call to Quit() will terminate the underlying 119*6777b538SAndroid Build Coastguard Worker // message loop. If a nested RunLoop continues running, the target may NEVER 120*6777b538SAndroid Build Coastguard Worker // terminate. 121*6777b538SAndroid Build Coastguard Worker void Quit(); 122*6777b538SAndroid Build Coastguard Worker void QuitWhenIdle(); 123*6777b538SAndroid Build Coastguard Worker 124*6777b538SAndroid Build Coastguard Worker // Returns a RepeatingClosure that safely calls Quit() or QuitWhenIdle() (has 125*6777b538SAndroid Build Coastguard Worker // no effect if the RunLoop instance is gone). 126*6777b538SAndroid Build Coastguard Worker // 127*6777b538SAndroid Build Coastguard Worker // The closures must be obtained from the thread owning the RunLoop but may 128*6777b538SAndroid Build Coastguard Worker // then be invoked from any thread. 129*6777b538SAndroid Build Coastguard Worker // 130*6777b538SAndroid Build Coastguard Worker // Returned closures may be safely: 131*6777b538SAndroid Build Coastguard Worker // * Passed to other threads. 132*6777b538SAndroid Build Coastguard Worker // * Run() from other threads, though this will quit the RunLoop 133*6777b538SAndroid Build Coastguard Worker // asynchronously. 134*6777b538SAndroid Build Coastguard Worker // * Run() after the RunLoop has stopped or been destroyed, in which case 135*6777b538SAndroid Build Coastguard Worker // they are a no-op). 136*6777b538SAndroid Build Coastguard Worker // * Run() before RunLoop::Run(), in which case RunLoop::Run() returns 137*6777b538SAndroid Build Coastguard Worker // immediately." 138*6777b538SAndroid Build Coastguard Worker // 139*6777b538SAndroid Build Coastguard Worker // Example: 140*6777b538SAndroid Build Coastguard Worker // RunLoop run_loop; 141*6777b538SAndroid Build Coastguard Worker // DoFooAsyncAndNotify(run_loop.QuitClosure()); 142*6777b538SAndroid Build Coastguard Worker // run_loop.Run(); 143*6777b538SAndroid Build Coastguard Worker // 144*6777b538SAndroid Build Coastguard Worker // Note that Quit() itself is thread-safe and may be invoked directly if you 145*6777b538SAndroid Build Coastguard Worker // have access to the RunLoop reference from another thread (e.g. from a 146*6777b538SAndroid Build Coastguard Worker // capturing lambda or test observer). 147*6777b538SAndroid Build Coastguard Worker [[nodiscard]] RepeatingClosure QuitClosure(); 148*6777b538SAndroid Build Coastguard Worker [[nodiscard]] RepeatingClosure QuitWhenIdleClosure(); 149*6777b538SAndroid Build Coastguard Worker 150*6777b538SAndroid Build Coastguard Worker // Returns true if Quit() or QuitWhenIdle() was called. 151*6777b538SAndroid Build Coastguard Worker bool AnyQuitCalled(); 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker // Returns true if there is an active RunLoop on this thread. 154*6777b538SAndroid Build Coastguard Worker // Safe to call before RegisterDelegateForCurrentThread(). 155*6777b538SAndroid Build Coastguard Worker static bool IsRunningOnCurrentThread(); 156*6777b538SAndroid Build Coastguard Worker 157*6777b538SAndroid Build Coastguard Worker // Returns true if there is an active RunLoop on this thread and it's nested 158*6777b538SAndroid Build Coastguard Worker // within another active RunLoop. 159*6777b538SAndroid Build Coastguard Worker // Safe to call before RegisterDelegateForCurrentThread(). 160*6777b538SAndroid Build Coastguard Worker static bool IsNestedOnCurrentThread(); 161*6777b538SAndroid Build Coastguard Worker 162*6777b538SAndroid Build Coastguard Worker // A NestingObserver is notified when a nested RunLoop begins and ends. 163*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT NestingObserver { 164*6777b538SAndroid Build Coastguard Worker public: 165*6777b538SAndroid Build Coastguard Worker // Notified before a nested loop starts running work on the current thread. 166*6777b538SAndroid Build Coastguard Worker virtual void OnBeginNestedRunLoop() = 0; 167*6777b538SAndroid Build Coastguard Worker // Notified after a nested loop is done running work on the current thread. OnExitNestedRunLoop()168*6777b538SAndroid Build Coastguard Worker virtual void OnExitNestedRunLoop() {} 169*6777b538SAndroid Build Coastguard Worker 170*6777b538SAndroid Build Coastguard Worker protected: 171*6777b538SAndroid Build Coastguard Worker virtual ~NestingObserver() = default; 172*6777b538SAndroid Build Coastguard Worker }; 173*6777b538SAndroid Build Coastguard Worker 174*6777b538SAndroid Build Coastguard Worker static void AddNestingObserverOnCurrentThread(NestingObserver* observer); 175*6777b538SAndroid Build Coastguard Worker static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer); 176*6777b538SAndroid Build Coastguard Worker 177*6777b538SAndroid Build Coastguard Worker // A RunLoop::Delegate is a generic interface that allows RunLoop to be 178*6777b538SAndroid Build Coastguard Worker // separate from the underlying implementation of the message loop for this 179*6777b538SAndroid Build Coastguard Worker // thread. It holds private state used by RunLoops on its associated thread. 180*6777b538SAndroid Build Coastguard Worker // One and only one RunLoop::Delegate must be registered on a given thread 181*6777b538SAndroid Build Coastguard Worker // via RunLoop::RegisterDelegateForCurrentThread() before RunLoop instances 182*6777b538SAndroid Build Coastguard Worker // and RunLoop static methods can be used on it. 183*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Delegate { 184*6777b538SAndroid Build Coastguard Worker public: 185*6777b538SAndroid Build Coastguard Worker Delegate(); 186*6777b538SAndroid Build Coastguard Worker Delegate(const Delegate&) = delete; 187*6777b538SAndroid Build Coastguard Worker Delegate& operator=(const Delegate&) = delete; 188*6777b538SAndroid Build Coastguard Worker virtual ~Delegate(); 189*6777b538SAndroid Build Coastguard Worker 190*6777b538SAndroid Build Coastguard Worker // Used by RunLoop to inform its Delegate to Run/Quit. Implementations are 191*6777b538SAndroid Build Coastguard Worker // expected to keep on running synchronously from the Run() call until the 192*6777b538SAndroid Build Coastguard Worker // eventual matching Quit() call or a delay of |timeout| expires. Upon 193*6777b538SAndroid Build Coastguard Worker // receiving a Quit() call or timing out it should return from the Run() 194*6777b538SAndroid Build Coastguard Worker // call as soon as possible without executing remaining tasks/messages. 195*6777b538SAndroid Build Coastguard Worker // Run() calls can nest in which case each Quit() call should result in the 196*6777b538SAndroid Build Coastguard Worker // topmost active Run() call returning. The only other trigger for Run() 197*6777b538SAndroid Build Coastguard Worker // to return is the |should_quit_when_idle_callback_| which the Delegate 198*6777b538SAndroid Build Coastguard Worker // should probe before sleeping when it becomes idle. 199*6777b538SAndroid Build Coastguard Worker // |application_tasks_allowed| is true if this is the first Run() call on 200*6777b538SAndroid Build Coastguard Worker // the stack or it was made from a nested RunLoop of 201*6777b538SAndroid Build Coastguard Worker // Type::kNestableTasksAllowed (otherwise this Run() level should only 202*6777b538SAndroid Build Coastguard Worker // process system tasks). 203*6777b538SAndroid Build Coastguard Worker virtual void Run(bool application_tasks_allowed, TimeDelta timeout) = 0; 204*6777b538SAndroid Build Coastguard Worker virtual void Quit() = 0; 205*6777b538SAndroid Build Coastguard Worker 206*6777b538SAndroid Build Coastguard Worker // Invoked right before a RunLoop enters a nested Run() call on this 207*6777b538SAndroid Build Coastguard Worker // Delegate iff this RunLoop is of type kNestableTasksAllowed. The Delegate 208*6777b538SAndroid Build Coastguard Worker // should ensure that the upcoming Run() call will result in processing 209*6777b538SAndroid Build Coastguard Worker // application tasks queued ahead of it without further probing. e.g. 210*6777b538SAndroid Build Coastguard Worker // message pumps on some platforms, like Mac, need an explicit request to 211*6777b538SAndroid Build Coastguard Worker // process application tasks when nested, otherwise they'll only wait for 212*6777b538SAndroid Build Coastguard Worker // system messages. 213*6777b538SAndroid Build Coastguard Worker virtual void EnsureWorkScheduled() = 0; 214*6777b538SAndroid Build Coastguard Worker 215*6777b538SAndroid Build Coastguard Worker protected: 216*6777b538SAndroid Build Coastguard Worker // Returns the result of this Delegate's |should_quit_when_idle_callback_|. 217*6777b538SAndroid Build Coastguard Worker // "protected" so it can be invoked only by the Delegate itself. The 218*6777b538SAndroid Build Coastguard Worker // Delegate is expected to quit Run() if this returns true. 219*6777b538SAndroid Build Coastguard Worker bool ShouldQuitWhenIdle(); 220*6777b538SAndroid Build Coastguard Worker 221*6777b538SAndroid Build Coastguard Worker private: 222*6777b538SAndroid Build Coastguard Worker // While the state is owned by the Delegate subclass, only RunLoop can use 223*6777b538SAndroid Build Coastguard Worker // it. 224*6777b538SAndroid Build Coastguard Worker friend class RunLoop; 225*6777b538SAndroid Build Coastguard Worker 226*6777b538SAndroid Build Coastguard Worker friend class ScopedDisallowRunningRunLoop; 227*6777b538SAndroid Build Coastguard Worker 228*6777b538SAndroid Build Coastguard Worker // A vector-based stack is more memory efficient than the default 229*6777b538SAndroid Build Coastguard Worker // deque-based stack as the active RunLoop stack isn't expected to ever 230*6777b538SAndroid Build Coastguard Worker // have more than a few entries. 231*6777b538SAndroid Build Coastguard Worker using RunLoopStack = 232*6777b538SAndroid Build Coastguard Worker stack<raw_ptr<RunLoop, VectorExperimental>, 233*6777b538SAndroid Build Coastguard Worker std::vector<raw_ptr<RunLoop, VectorExperimental>>>; 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker RunLoopStack active_run_loops_; 236*6777b538SAndroid Build Coastguard Worker ObserverList<RunLoop::NestingObserver>::Unchecked nesting_observers_; 237*6777b538SAndroid Build Coastguard Worker 238*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 239*6777b538SAndroid Build Coastguard Worker bool allow_running_for_testing_ = true; 240*6777b538SAndroid Build Coastguard Worker #endif 241*6777b538SAndroid Build Coastguard Worker 242*6777b538SAndroid Build Coastguard Worker // True once this Delegate is bound to a thread via 243*6777b538SAndroid Build Coastguard Worker // RegisterDelegateForCurrentThread(). 244*6777b538SAndroid Build Coastguard Worker bool bound_ = false; 245*6777b538SAndroid Build Coastguard Worker 246*6777b538SAndroid Build Coastguard Worker // Thread-affine per its use of TLS. 247*6777b538SAndroid Build Coastguard Worker THREAD_CHECKER(bound_thread_checker_); 248*6777b538SAndroid Build Coastguard Worker }; 249*6777b538SAndroid Build Coastguard Worker 250*6777b538SAndroid Build Coastguard Worker // Registers |delegate| on the current thread. Must be called once and only 251*6777b538SAndroid Build Coastguard Worker // once per thread before using RunLoop methods on it. |delegate| is from then 252*6777b538SAndroid Build Coastguard Worker // on forever bound to that thread (including its destruction). 253*6777b538SAndroid Build Coastguard Worker static void RegisterDelegateForCurrentThread(Delegate* new_delegate); 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker // Support for //base/test/scoped_run_loop_timeout.h. 256*6777b538SAndroid Build Coastguard Worker // This must be public for access by the implementation code in run_loop.cc. 257*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT RunLoopTimeout { 258*6777b538SAndroid Build Coastguard Worker RunLoopTimeout(); 259*6777b538SAndroid Build Coastguard Worker ~RunLoopTimeout(); 260*6777b538SAndroid Build Coastguard Worker TimeDelta timeout; 261*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(const Location&)> on_timeout; 262*6777b538SAndroid Build Coastguard Worker }; 263*6777b538SAndroid Build Coastguard Worker 264*6777b538SAndroid Build Coastguard Worker private: 265*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(SingleThreadTaskExecutorTypedTest, 266*6777b538SAndroid Build Coastguard Worker RunLoopQuitOrderAfter); 267*6777b538SAndroid Build Coastguard Worker 268*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) 269*6777b538SAndroid Build Coastguard Worker // Android doesn't support the blocking RunLoop::Run, so it calls 270*6777b538SAndroid Build Coastguard Worker // BeforeRun and AfterRun directly. 271*6777b538SAndroid Build Coastguard Worker friend class MessagePumpAndroid; 272*6777b538SAndroid Build Coastguard Worker #endif 273*6777b538SAndroid Build Coastguard Worker 274*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_IOS) 275*6777b538SAndroid Build Coastguard Worker // iOS doesn't support the blocking RunLoop::Run, so it calls 276*6777b538SAndroid Build Coastguard Worker // BeforeRun directly. 277*6777b538SAndroid Build Coastguard Worker friend class MessagePumpUIApplication; 278*6777b538SAndroid Build Coastguard Worker #endif 279*6777b538SAndroid Build Coastguard Worker 280*6777b538SAndroid Build Coastguard Worker // Support for //base/test/scoped_run_loop_timeout.h. 281*6777b538SAndroid Build Coastguard Worker friend class test::ScopedRunLoopTimeout; 282*6777b538SAndroid Build Coastguard Worker friend class test::ScopedDisableRunLoopTimeout; 283*6777b538SAndroid Build Coastguard Worker 284*6777b538SAndroid Build Coastguard Worker static void SetTimeoutForCurrentThread(const RunLoopTimeout* timeout); 285*6777b538SAndroid Build Coastguard Worker static const RunLoopTimeout* GetTimeoutForCurrentThread(); 286*6777b538SAndroid Build Coastguard Worker 287*6777b538SAndroid Build Coastguard Worker // Return false to abort the Run. 288*6777b538SAndroid Build Coastguard Worker bool BeforeRun(); 289*6777b538SAndroid Build Coastguard Worker void AfterRun(); 290*6777b538SAndroid Build Coastguard Worker 291*6777b538SAndroid Build Coastguard Worker // A cached reference of RunLoop::Delegate for the thread driven by this 292*6777b538SAndroid Build Coastguard Worker // RunLoop for quick access without using TLS (also allows access to state 293*6777b538SAndroid Build Coastguard Worker // from another sequence during Run(), ref. |sequence_checker_| below). 294*6777b538SAndroid Build Coastguard Worker const raw_ptr<Delegate, DanglingUntriaged> delegate_; 295*6777b538SAndroid Build Coastguard Worker 296*6777b538SAndroid Build Coastguard Worker const Type type_; 297*6777b538SAndroid Build Coastguard Worker 298*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 299*6777b538SAndroid Build Coastguard Worker bool run_allowed_ = true; 300*6777b538SAndroid Build Coastguard Worker #endif 301*6777b538SAndroid Build Coastguard Worker 302*6777b538SAndroid Build Coastguard Worker bool quit_called_ = false; 303*6777b538SAndroid Build Coastguard Worker bool running_ = false; 304*6777b538SAndroid Build Coastguard Worker 305*6777b538SAndroid Build Coastguard Worker // Used to record that QuitWhenIdle() was called on this RunLoop. 306*6777b538SAndroid Build Coastguard Worker bool quit_when_idle_called_ = false; 307*6777b538SAndroid Build Coastguard Worker // Whether the Delegate should quit Run() once it becomes idle (it's 308*6777b538SAndroid Build Coastguard Worker // responsible for probing this state via ShouldQuitWhenIdle()). This state is 309*6777b538SAndroid Build Coastguard Worker // stored here rather than pushed to Delegate to support nested RunLoops. 310*6777b538SAndroid Build Coastguard Worker bool quit_when_idle_ = false; 311*6777b538SAndroid Build Coastguard Worker 312*6777b538SAndroid Build Coastguard Worker // RunLoop is not thread-safe. Its state/methods, unless marked as such, may 313*6777b538SAndroid Build Coastguard Worker // not be accessed from any other sequence than the thread it was constructed 314*6777b538SAndroid Build Coastguard Worker // on. Exception: RunLoop can be safely accessed from one other sequence (or 315*6777b538SAndroid Build Coastguard Worker // single parallel task) during Run() -- e.g. to Quit() without having to 316*6777b538SAndroid Build Coastguard Worker // plumb SingleThreadTaskRunner::GetCurrentDefault() throughout a test to 317*6777b538SAndroid Build Coastguard Worker // repost QuitClosure to origin thread. 318*6777b538SAndroid Build Coastguard Worker SEQUENCE_CHECKER(sequence_checker_); 319*6777b538SAndroid Build Coastguard Worker 320*6777b538SAndroid Build Coastguard Worker const scoped_refptr<SingleThreadTaskRunner> origin_task_runner_; 321*6777b538SAndroid Build Coastguard Worker 322*6777b538SAndroid Build Coastguard Worker // WeakPtrFactory for QuitClosure safety. 323*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<RunLoop> weak_factory_{this}; 324*6777b538SAndroid Build Coastguard Worker }; 325*6777b538SAndroid Build Coastguard Worker 326*6777b538SAndroid Build Coastguard Worker // RunLoop::Run() will DCHECK if called while there's a 327*6777b538SAndroid Build Coastguard Worker // ScopedDisallowRunningRunLoop in scope on its thread. This is useful to add 328*6777b538SAndroid Build Coastguard Worker // safety to some test constructs which allow multiple task runners to share the 329*6777b538SAndroid Build Coastguard Worker // main thread in unit tests. While the main thread can be shared by multiple 330*6777b538SAndroid Build Coastguard Worker // runners to deterministically fake multi threading, there can still only be a 331*6777b538SAndroid Build Coastguard Worker // single RunLoop::Delegate per thread and RunLoop::Run() should only be invoked 332*6777b538SAndroid Build Coastguard Worker // from it (or it would result in incorrectly driving TaskRunner A while in 333*6777b538SAndroid Build Coastguard Worker // TaskRunner B's context). 334*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowRunningRunLoop { 335*6777b538SAndroid Build Coastguard Worker public: 336*6777b538SAndroid Build Coastguard Worker ScopedDisallowRunningRunLoop(); 337*6777b538SAndroid Build Coastguard Worker ScopedDisallowRunningRunLoop(const ScopedDisallowRunningRunLoop&) = delete; 338*6777b538SAndroid Build Coastguard Worker ScopedDisallowRunningRunLoop& operator=(const ScopedDisallowRunningRunLoop&) = 339*6777b538SAndroid Build Coastguard Worker delete; 340*6777b538SAndroid Build Coastguard Worker ~ScopedDisallowRunningRunLoop(); 341*6777b538SAndroid Build Coastguard Worker 342*6777b538SAndroid Build Coastguard Worker private: 343*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 344*6777b538SAndroid Build Coastguard Worker raw_ptr<RunLoop::Delegate> current_delegate_; 345*6777b538SAndroid Build Coastguard Worker const bool previous_run_allowance_; 346*6777b538SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 347*6777b538SAndroid Build Coastguard Worker }; 348*6777b538SAndroid Build Coastguard Worker 349*6777b538SAndroid Build Coastguard Worker } // namespace base 350*6777b538SAndroid Build Coastguard Worker 351*6777b538SAndroid Build Coastguard Worker #endif // BASE_RUN_LOOP_H_ 352