1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_RUN_LOOP_H_ 6 #define BASE_RUN_LOOP_H_ 7 8 #include <utility> 9 #include <vector> 10 11 #include "base/base_export.h" 12 #include "base/callback.h" 13 #include "base/containers/stack.h" 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/observer_list.h" 18 #include "base/sequence_checker.h" 19 #include "base/threading/thread_checker.h" 20 #include "build/build_config.h" 21 22 namespace base { 23 #if defined(OS_ANDROID) 24 class MessagePumpForUI; 25 #endif 26 27 #if defined(OS_IOS) 28 class MessagePumpUIApplication; 29 #endif 30 31 class SingleThreadTaskRunner; 32 33 // Helper class to run the RunLoop::Delegate associated with the current thread. 34 // A RunLoop::Delegate must have been bound to this thread (ref. 35 // RunLoop::RegisterDelegateForCurrentThread()) prior to using any of RunLoop's 36 // member and static methods unless explicitly indicated otherwise (e.g. 37 // IsRunning/IsNestedOnCurrentThread()). RunLoop::Run can only be called once 38 // per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run 39 // a nested RunLoop but please do not use nested loops in production code! 40 class BASE_EXPORT RunLoop { 41 public: 42 // The type of RunLoop: a kDefault RunLoop at the top-level (non-nested) will 43 // process system and application tasks assigned to its Delegate. When nested 44 // however a kDefault RunLoop will only process system tasks while a 45 // kNestableTasksAllowed RunLoop will continue to process application tasks 46 // even if nested. 47 // 48 // This is relevant in the case of recursive RunLoops. Some unwanted run loops 49 // may occur when using common controls or printer functions. By default, 50 // recursive task processing is disabled. 51 // 52 // In general, nestable RunLoops are to be avoided. They are dangerous and 53 // difficult to get right, so please use with extreme caution. 54 // 55 // A specific example where this makes a difference is: 56 // - The thread is running a RunLoop. 57 // - It receives a task #1 and executes it. 58 // - The task #1 implicitly starts a RunLoop, like a MessageBox in the unit 59 // test. This can also be StartDoc or GetSaveFileName. 60 // - The thread receives a task #2 before or while in this second RunLoop. 61 // - With a kNestableTasksAllowed RunLoop, the task #2 will run right away. 62 // Otherwise, it will get executed right after task #1 completes in the main 63 // RunLoop. 64 enum class Type { 65 kDefault, 66 kNestableTasksAllowed, 67 }; 68 69 RunLoop(Type type = Type::kDefault); 70 ~RunLoop(); 71 72 // Run the current RunLoop::Delegate. This blocks until Quit is called. Before 73 // calling Run, be sure to grab the QuitClosure in order to stop the 74 // RunLoop::Delegate asynchronously. 75 void Run(); 76 77 // Run the current RunLoop::Delegate until it doesn't find any tasks or 78 // messages in its queue (it goes idle). WARNING: This may never return! Only 79 // use this when repeating tasks such as animated web pages have been shut 80 // down. 81 void RunUntilIdle(); 82 running()83 bool running() const { 84 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 85 return running_; 86 } 87 88 // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an 89 // earlier call to Run() when there aren't any tasks or messages in the queue. 90 // 91 // These methods are thread-safe but note that Quit() is best-effort when 92 // called from another thread (will quit soon but tasks that were already 93 // queued on this RunLoop will get to run first). 94 // 95 // There can be other nested RunLoops servicing the same task queue. Quitting 96 // one RunLoop has no bearing on the others. Quit() and QuitWhenIdle() can be 97 // called before, during or after Run(). If called before Run(), Run() will 98 // return immediately when called. Calling Quit() or QuitWhenIdle() after the 99 // RunLoop has already finished running has no effect. 100 // 101 // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will 102 // terminate the targetted message loop. If a nested RunLoop continues 103 // running, the target may NEVER terminate. It is very easy to livelock (run 104 // forever) in such a case. 105 void Quit(); 106 void QuitWhenIdle(); 107 108 // Convenience methods to get a closure that safely calls Quit() or 109 // QuitWhenIdle() (has no effect if the RunLoop instance is gone). 110 // 111 // The resulting Closure is thread-safe (note however that invoking the 112 // QuitClosure() from another thread than this RunLoop's will result in an 113 // asynchronous rather than immediate Quit()). 114 // 115 // Example: 116 // RunLoop run_loop; 117 // PostTask(run_loop.QuitClosure()); 118 // run_loop.Run(); 119 base::Closure QuitClosure(); 120 base::Closure QuitWhenIdleClosure(); 121 122 // Returns true if there is an active RunLoop on this thread. 123 // Safe to call before RegisterDelegateForCurrentThread(). 124 static bool IsRunningOnCurrentThread(); 125 126 // Returns true if there is an active RunLoop on this thread and it's nested 127 // within another active RunLoop. 128 // Safe to call before RegisterDelegateForCurrentThread(). 129 static bool IsNestedOnCurrentThread(); 130 131 // A NestingObserver is notified when a nested RunLoop begins and ends. 132 class BASE_EXPORT NestingObserver { 133 public: 134 // Notified before a nested loop starts running work on the current thread. 135 virtual void OnBeginNestedRunLoop() = 0; 136 // Notified after a nested loop is done running work on the current thread. OnExitNestedRunLoop()137 virtual void OnExitNestedRunLoop() {} 138 139 protected: 140 virtual ~NestingObserver() = default; 141 }; 142 143 static void AddNestingObserverOnCurrentThread(NestingObserver* observer); 144 static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer); 145 146 // A RunLoop::Delegate is a generic interface that allows RunLoop to be 147 // separate from the underlying implementation of the message loop for this 148 // thread. It holds private state used by RunLoops on its associated thread. 149 // One and only one RunLoop::Delegate must be registered on a given thread 150 // via RunLoop::RegisterDelegateForCurrentThread() before RunLoop instances 151 // and RunLoop static methods can be used on it. 152 class BASE_EXPORT Delegate { 153 public: 154 Delegate(); 155 virtual ~Delegate(); 156 157 // Used by RunLoop to inform its Delegate to Run/Quit. Implementations are 158 // expected to keep on running synchronously from the Run() call until the 159 // eventual matching Quit() call. Upon receiving a Quit() call it should 160 // return from the Run() call as soon as possible without executing 161 // remaining tasks/messages. Run() calls can nest in which case each Quit() 162 // call should result in the topmost active Run() call returning. The only 163 // other trigger for Run() to return is the 164 // |should_quit_when_idle_callback_| which the Delegate should probe before 165 // sleeping when it becomes idle. |application_tasks_allowed| is true if 166 // this is the first Run() call on the stack or it was made from a nested 167 // RunLoop of Type::kNestableTasksAllowed (otherwise this Run() level should 168 // only process system tasks). 169 virtual void Run(bool application_tasks_allowed) = 0; 170 virtual void Quit() = 0; 171 172 // Invoked right before a RunLoop enters a nested Run() call on this 173 // Delegate iff this RunLoop is of type kNestableTasksAllowed. The Delegate 174 // should ensure that the upcoming Run() call will result in processing 175 // application tasks queued ahead of it without further probing. e.g. 176 // message pumps on some platforms, like Mac, need an explicit request to 177 // process application tasks when nested, otherwise they'll only wait for 178 // system messages. 179 virtual void EnsureWorkScheduled() = 0; 180 181 protected: 182 // Returns the result of this Delegate's |should_quit_when_idle_callback_|. 183 // "protected" so it can be invoked only by the Delegate itself. 184 bool ShouldQuitWhenIdle(); 185 186 private: 187 // While the state is owned by the Delegate subclass, only RunLoop can use 188 // it. 189 friend class RunLoop; 190 191 // A vector-based stack is more memory efficient than the default 192 // deque-based stack as the active RunLoop stack isn't expected to ever 193 // have more than a few entries. 194 using RunLoopStack = base::stack<RunLoop*, std::vector<RunLoop*>>; 195 196 RunLoopStack active_run_loops_; 197 ObserverList<RunLoop::NestingObserver> nesting_observers_; 198 199 #if DCHECK_IS_ON() 200 bool allow_running_for_testing_ = true; 201 #endif 202 203 // True once this Delegate is bound to a thread via 204 // RegisterDelegateForCurrentThread(). 205 bool bound_ = false; 206 207 // Thread-affine per its use of TLS. 208 THREAD_CHECKER(bound_thread_checker_); 209 210 DISALLOW_COPY_AND_ASSIGN(Delegate); 211 }; 212 213 // Registers |delegate| on the current thread. Must be called once and only 214 // once per thread before using RunLoop methods on it. |delegate| is from then 215 // on forever bound to that thread (including its destruction). 216 static void RegisterDelegateForCurrentThread(Delegate* delegate); 217 218 // Quits the active RunLoop (when idle) -- there must be one. These were 219 // introduced as prefered temporary replacements to the long deprecated 220 // MessageLoop::Quit(WhenIdle)(Closure) methods. Callers should properly plumb 221 // a reference to the appropriate RunLoop instance (or its QuitClosure) 222 // instead of using these in order to link Run()/Quit() to a single RunLoop 223 // instance and increase readability. 224 static void QuitCurrentDeprecated(); 225 static void QuitCurrentWhenIdleDeprecated(); 226 static Closure QuitCurrentWhenIdleClosureDeprecated(); 227 228 // Run() will DCHECK if called while there's a ScopedDisallowRunningForTesting 229 // in scope on its thread. This is useful to add safety to some test 230 // constructs which allow multiple task runners to share the main thread in 231 // unit tests. While the main thread can be shared by multiple runners to 232 // deterministically fake multi threading, there can still only be a single 233 // RunLoop::Delegate per thread and RunLoop::Run() should only be invoked from 234 // it (or it would result in incorrectly driving TaskRunner A while in 235 // TaskRunner B's context). 236 class BASE_EXPORT ScopedDisallowRunningForTesting { 237 public: 238 ScopedDisallowRunningForTesting(); 239 ~ScopedDisallowRunningForTesting(); 240 241 private: 242 #if DCHECK_IS_ON() 243 Delegate* current_delegate_; 244 const bool previous_run_allowance_; 245 #endif // DCHECK_IS_ON() 246 247 DISALLOW_COPY_AND_ASSIGN(ScopedDisallowRunningForTesting); 248 }; 249 250 private: 251 FRIEND_TEST_ALL_PREFIXES(MessageLoopTypedTest, RunLoopQuitOrderAfter); 252 253 #if defined(OS_ANDROID) 254 // Android doesn't support the blocking RunLoop::Run, so it calls 255 // BeforeRun and AfterRun directly. 256 friend class base::MessagePumpForUI; 257 #endif 258 259 #if defined(OS_IOS) 260 // iOS doesn't support the blocking RunLoop::Run, so it calls 261 // BeforeRun directly. 262 friend class base::MessagePumpUIApplication; 263 #endif 264 265 // Return false to abort the Run. 266 bool BeforeRun(); 267 void AfterRun(); 268 269 // A copy of RunLoop::Delegate for the thread driven by tis RunLoop for quick 270 // access without using TLS (also allows access to state from another sequence 271 // during Run(), ref. |sequence_checker_| below). 272 Delegate* delegate_; 273 274 const Type type_; 275 276 #if DCHECK_IS_ON() 277 bool run_called_ = false; 278 #endif 279 280 bool quit_called_ = false; 281 bool running_ = false; 282 // Used to record that QuitWhenIdle() was called on this RunLoop, meaning that 283 // the Delegate should quit Run() once it becomes idle (it's responsible for 284 // probing this state via ShouldQuitWhenIdle()). This state is stored here 285 // rather than pushed to Delegate to support nested RunLoops. 286 bool quit_when_idle_received_ = false; 287 288 // True if use of QuitCurrent*Deprecated() is allowed. Taking a Quit*Closure() 289 // from a RunLoop implicitly sets this to false, so QuitCurrent*Deprecated() 290 // cannot be used while that RunLoop is being Run(). 291 bool allow_quit_current_deprecated_ = true; 292 293 // RunLoop is not thread-safe. Its state/methods, unless marked as such, may 294 // not be accessed from any other sequence than the thread it was constructed 295 // on. Exception: RunLoop can be safely accessed from one other sequence (or 296 // single parallel task) during Run() -- e.g. to Quit() without having to 297 // plumb ThreatTaskRunnerHandle::Get() throughout a test to repost QuitClosure 298 // to origin thread. 299 SEQUENCE_CHECKER(sequence_checker_); 300 301 const scoped_refptr<SingleThreadTaskRunner> origin_task_runner_; 302 303 // WeakPtrFactory for QuitClosure safety. 304 base::WeakPtrFactory<RunLoop> weak_factory_; 305 306 DISALLOW_COPY_AND_ASSIGN(RunLoop); 307 }; 308 309 } // namespace base 310 311 #endif // BASE_RUN_LOOP_H_ 312