blob: e43c4fcece2b3141594cf4a67f6b6597a80aa2ee [file] [log] [blame]
[email protected]8e937c1e2012-06-28 22:57:301// 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_
[email protected]8e937c1e2012-06-28 22:57:307
Gabriel Charette1ef212b2017-12-03 12:47:218#include <utility>
gab273551962017-05-18 06:01:109#include <vector>
10
[email protected]8e937c1e2012-06-28 22:57:3011#include "base/base_export.h"
12#include "base/callback.h"
Brett Wilson1f07f20e2017-10-02 18:55:2813#include "base/containers/stack.h"
avi9b6f42932015-12-26 22:15:1414#include "base/macros.h"
gabcf5e4ce2017-05-19 22:56:5715#include "base/memory/ref_counted.h"
[email protected]8e937c1e2012-06-28 22:57:3016#include "base/memory/weak_ptr.h"
gab273551962017-05-18 06:01:1017#include "base/observer_list.h"
gab980a52712017-05-18 16:20:1618#include "base/sequence_checker.h"
ahest72c1b442016-12-09 20:40:3819#include "base/threading/thread_checker.h"
avi9b6f42932015-12-26 22:15:1420#include "build/build_config.h"
[email protected]8e937c1e2012-06-28 22:57:3021
22namespace base {
23#if defined(OS_ANDROID)
24class MessagePumpForUI;
25#endif
26
[email protected]feb727e2012-07-13 11:02:5727#if defined(OS_IOS)
28class MessagePumpUIApplication;
29#endif
30
gabcf5e4ce2017-05-19 22:56:5731class SingleThreadTaskRunner;
32
gab273551962017-05-18 06:01:1033// 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
[email protected]8e937c1e2012-06-28 22:57:3038// per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run
gab273551962017-05-18 06:01:1039// a nested RunLoop but please do not use nested loops in production code!
[email protected]8e937c1e2012-06-28 22:57:3040class BASE_EXPORT RunLoop {
41 public:
Gabriel Charette3ff403e2017-08-07 04:22:4842 // 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. To further
54 // protect this: kNestableTasksAllowed RunLoops are only allowed on threads
55 // where IsNestingAllowedOnCurrentThread().
56 //
57 // A specific example where this makes a difference is:
58 // - The thread is running a RunLoop.
59 // - It receives a task #1 and executes it.
60 // - The task #1 implicitly starts a RunLoop, like a MessageBox in the unit
61 // test. This can also be StartDoc or GetSaveFileName.
62 // - The thread receives a task #2 before or while in this second RunLoop.
63 // - With a kNestableTasksAllowed RunLoop, the task #2 will run right away.
64 // Otherwise, it will get executed right after task #1 completes in the main
65 // RunLoop.
66 enum class Type {
67 kDefault,
68 kNestableTasksAllowed,
69 };
70
71 RunLoop(Type type = Type::kDefault);
[email protected]8e937c1e2012-06-28 22:57:3072 ~RunLoop();
73
gab273551962017-05-18 06:01:1074 // Run the current RunLoop::Delegate. This blocks until Quit is called. Before
blundell69c25492016-02-04 08:10:4575 // calling Run, be sure to grab the QuitClosure in order to stop the
Gabriel Charetted9839bc2017-07-29 14:17:4776 // RunLoop::Delegate asynchronously.
[email protected]8e937c1e2012-06-28 22:57:3077 void Run();
78
gab273551962017-05-18 06:01:1079 // Run the current RunLoop::Delegate until it doesn't find any tasks or
80 // messages in its queue (it goes idle). WARNING: This may never return! Only
81 // use this when repeating tasks such as animated web pages have been shut
82 // down.
[email protected]8e937c1e2012-06-28 22:57:3083 void RunUntilIdle();
84
gab7af9dc02017-05-05 13:38:5485 bool running() const {
gab980a52712017-05-18 16:20:1686 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
gab7af9dc02017-05-05 13:38:5487 return running_;
88 }
[email protected]8e937c1e2012-06-28 22:57:3089
fdoraya4f28ec2016-06-10 00:08:5890 // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an
91 // earlier call to Run() when there aren't any tasks or messages in the queue.
[email protected]8e937c1e2012-06-28 22:57:3092 //
gabcf5e4ce2017-05-19 22:56:5793 // These methods are thread-safe but note that Quit() is best-effort when
94 // called from another thread (will quit soon but tasks that were already
95 // queued on this RunLoop will get to run first).
96 //
Gabriel Charetted9839bc2017-07-29 14:17:4797 // There can be other nested RunLoops servicing the same task queue. Quitting
98 // one RunLoop has no bearing on the others. Quit() and QuitWhenIdle() can be
99 // called before, during or after Run(). If called before Run(), Run() will
100 // return immediately when called. Calling Quit() or QuitWhenIdle() after the
101 // RunLoop has already finished running has no effect.
fdoraya4f28ec2016-06-10 00:08:58102 //
103 // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will
Gabriel Charette3ff403e2017-08-07 04:22:48104 // terminate the targetted message loop. If a nested RunLoop continues
fdoraya4f28ec2016-06-10 00:08:58105 // running, the target may NEVER terminate. It is very easy to livelock (run
106 // forever) in such a case.
[email protected]8e937c1e2012-06-28 22:57:30107 void Quit();
fdoraya4f28ec2016-06-10 00:08:58108 void QuitWhenIdle();
[email protected]8e937c1e2012-06-28 22:57:30109
fdoraya3658602016-06-10 18:23:15110 // Convenience methods to get a closure that safely calls Quit() or
111 // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
[email protected]8e937c1e2012-06-28 22:57:30112 //
gabcf5e4ce2017-05-19 22:56:57113 // The resulting Closure is thread-safe (note however that invoking the
114 // QuitClosure() from another thread than this RunLoop's will result in an
115 // asynchronous rather than immediate Quit()).
116 //
[email protected]8e937c1e2012-06-28 22:57:30117 // Example:
118 // RunLoop run_loop;
119 // PostTask(run_loop.QuitClosure());
120 // run_loop.Run();
121 base::Closure QuitClosure();
fdoraya3658602016-06-10 18:23:15122 base::Closure QuitWhenIdleClosure();
[email protected]8e937c1e2012-06-28 22:57:30123
gab7af9dc02017-05-05 13:38:54124 // Returns true if there is an active RunLoop on this thread.
gab273551962017-05-18 06:01:10125 // Safe to call before RegisterDelegateForCurrentThread().
gab7af9dc02017-05-05 13:38:54126 static bool IsRunningOnCurrentThread();
127
128 // Returns true if there is an active RunLoop on this thread and it's nested
129 // within another active RunLoop.
gab273551962017-05-18 06:01:10130 // Safe to call before RegisterDelegateForCurrentThread().
gab7af9dc02017-05-05 13:38:54131 static bool IsNestedOnCurrentThread();
132
Gabriel Charette3ff403e2017-08-07 04:22:48133 // A NestingObserver is notified when a nested RunLoop begins. The observers
gab7af9dc02017-05-05 13:38:54134 // are notified before the current thread's RunLoop::Delegate::Run() is
135 // invoked and nested work begins.
136 class BASE_EXPORT NestingObserver {
137 public:
138 virtual void OnBeginNestedRunLoop() = 0;
139
140 protected:
141 virtual ~NestingObserver() = default;
142 };
143
144 static void AddNestingObserverOnCurrentThread(NestingObserver* observer);
145 static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer);
146
147 // Returns true if nesting is allowed on this thread.
148 static bool IsNestingAllowedOnCurrentThread();
149
150 // Disallow nesting. After this is called, running a nested RunLoop or calling
151 // Add/RemoveNestingObserverOnCurrentThread() on this thread will crash.
152 static void DisallowNestingOnCurrentThread();
153
gab273551962017-05-18 06:01:10154 // A RunLoop::Delegate is a generic interface that allows RunLoop to be
Gabriel Charettea3ec9612017-12-14 17:22:40155 // separate from the underlying implementation of the message loop for this
gab273551962017-05-18 06:01:10156 // thread. It holds private state used by RunLoops on its associated thread.
157 // One and only one RunLoop::Delegate must be registered on a given thread
158 // via RunLoop::RegisterDelegateForCurrentThread() before RunLoop instances
159 // and RunLoop static methods can be used on it.
160 class BASE_EXPORT Delegate {
Gabriel Charette46c535d22017-12-03 12:14:01161 public:
Gabriel Charettea3ec9612017-12-14 17:22:40162 // A Callback which returns true if the Delegate should return from the
163 // topmost Run() when it becomes idle. The Delegate is responsible for
164 // probing this when it becomes idle.
165 using ShouldQuitWhenIdleCallback = RepeatingCallback<bool(void)>;
166
gab273551962017-05-18 06:01:10167 Delegate();
Gabriel Charette1ef212b2017-12-03 12:47:21168 virtual ~Delegate();
gab273551962017-05-18 06:01:10169
gab273551962017-05-18 06:01:10170 // Used by RunLoop to inform its Delegate to Run/Quit. Implementations are
171 // expected to keep on running synchronously from the Run() call until the
172 // eventual matching Quit() call. Upon receiving a Quit() call it should
173 // return from the Run() call as soon as possible without executing
174 // remaining tasks/messages. Run() calls can nest in which case each Quit()
Gabriel Charette3ff403e2017-08-07 04:22:48175 // call should result in the topmost active Run() call returning. The only
Gabriel Charettea3ec9612017-12-14 17:22:40176 // other trigger for Run() to return is the
177 // |should_quit_when_idle_callback_| which the Delegate should probe before
178 // sleeping when it becomes idle. |application_tasks_allowed| is true if
179 // this is the first Run() call on the stack or it was made from a nested
180 // RunLoop of Type::kNestableTasksAllowed (otherwise this Run() level should
181 // only process system tasks).
Gabriel Charetteb030a4a2017-10-26 01:04:40182 virtual void Run(bool application_tasks_allowed) = 0;
gab273551962017-05-18 06:01:10183 virtual void Quit() = 0;
184
Gabriel Charette3ff403e2017-08-07 04:22:48185 // Invoked right before a RunLoop enters a nested Run() call on this
186 // Delegate iff this RunLoop is of type kNestableTasksAllowed. The Delegate
187 // should ensure that the upcoming Run() call will result in processing
188 // application tasks queued ahead of it without further probing. e.g.
189 // message pumps on some platforms, like Mac, need an explicit request to
190 // process application tasks when nested, otherwise they'll only wait for
191 // system messages.
192 virtual void EnsureWorkScheduled() = 0;
193
Gabriel Charettea3ec9612017-12-14 17:22:40194 protected:
195 // Returns the result of this Delegate's |should_quit_when_idle_callback_|.
196 // "protected" so it can be invoked only by the Delegate itself.
197 bool ShouldQuitWhenIdle();
198
Gabriel Charette46c535d22017-12-03 12:14:01199 private:
200 // While the state is owned by the Delegate subclass, only RunLoop can use
201 // it.
202 friend class RunLoop;
203
gab273551962017-05-18 06:01:10204 // A vector-based stack is more memory efficient than the default
205 // deque-based stack as the active RunLoop stack isn't expected to ever
206 // have more than a few entries.
Brett Wilson1f07f20e2017-10-02 18:55:28207 using RunLoopStack = base::stack<RunLoop*, std::vector<RunLoop*>>;
gab273551962017-05-18 06:01:10208
209 bool allow_nesting_ = true;
210 RunLoopStack active_run_loops_;
211 ObserverList<RunLoop::NestingObserver> nesting_observers_;
212
Gabriel Charettea44975052017-08-21 23:14:04213#if DCHECK_IS_ON()
214 bool allow_running_for_testing_ = true;
215#endif
216
gab273551962017-05-18 06:01:10217 // True once this Delegate is bound to a thread via
218 // RegisterDelegateForCurrentThread().
219 bool bound_ = false;
220
Gabriel Charettea3ec9612017-12-14 17:22:40221 ShouldQuitWhenIdleCallback should_quit_when_idle_callback_;
222
gab980a52712017-05-18 16:20:16223 // Thread-affine per its use of TLS.
gab273551962017-05-18 06:01:10224 THREAD_CHECKER(bound_thread_checker_);
225
gab273551962017-05-18 06:01:10226 DISALLOW_COPY_AND_ASSIGN(Delegate);
227 };
228
229 // Registers |delegate| on the current thread. Must be called once and only
230 // once per thread before using RunLoop methods on it. |delegate| is from then
Gabriel Charettea3ec9612017-12-14 17:22:40231 // on forever bound to that thread (including its destruction).
232 static void RegisterDelegateForCurrentThread(Delegate* delegate);
gab273551962017-05-18 06:01:10233
Gabriel Charette1ef212b2017-12-03 12:47:21234 // Akin to RegisterDelegateForCurrentThread but overrides an existing Delegate
Gabriel Charettea3ec9612017-12-14 17:22:40235 // (there must be one). Returning the overridden Delegate which the caller is
236 // now in charge of driving. |override_should_quit_when_idle_callback|
237 // specifies will replace the overridden Delegate's
238 // |should_quit_when_idle_callback_|, giving full control to |delegate|.
239 static Delegate* OverrideDelegateForCurrentThreadForTesting(
240 Delegate* delegate,
241 Delegate::ShouldQuitWhenIdleCallback
242 overriding_should_quit_when_idle_callback);
Gabriel Charette1ef212b2017-12-03 12:47:21243
Gabriel Charette0592c3a2017-07-26 12:02:04244 // Quits the active RunLoop (when idle) -- there must be one. These were
245 // introduced as prefered temporary replacements to the long deprecated
246 // MessageLoop::Quit(WhenIdle) methods. Callers should properly plumb a
247 // reference to the appropriate RunLoop instance (or its QuitClosure) instead
248 // of using these in order to link Run()/Quit() to a single RunLoop instance
249 // and increase readability.
250 static void QuitCurrentDeprecated();
251 static void QuitCurrentWhenIdleDeprecated();
252
Gabriel Charettea44975052017-08-21 23:14:04253 // Run() will DCHECK if called while there's a ScopedDisallowRunningForTesting
254 // in scope on its thread. This is useful to add safety to some test
255 // constructs which allow multiple task runners to share the main thread in
256 // unit tests. While the main thread can be shared by multiple runners to
257 // deterministically fake multi threading, there can still only be a single
258 // RunLoop::Delegate per thread and RunLoop::Run() should only be invoked from
259 // it (or it would result in incorrectly driving TaskRunner A while in
260 // TaskRunner B's context).
261 class BASE_EXPORT ScopedDisallowRunningForTesting {
262 public:
263 ScopedDisallowRunningForTesting();
264 ~ScopedDisallowRunningForTesting();
265
266 private:
267#if DCHECK_IS_ON()
268 Delegate* current_delegate_;
269 const bool previous_run_allowance_;
270#endif // DCHECK_IS_ON()
271
272 DISALLOW_COPY_AND_ASSIGN(ScopedDisallowRunningForTesting);
273 };
274
[email protected]8e937c1e2012-06-28 22:57:30275 private:
[email protected]8e937c1e2012-06-28 22:57:30276#if defined(OS_ANDROID)
Gabriel Charettee2b632b2017-08-02 03:52:16277 // Android doesn't support the blocking RunLoop::Run, so it calls
[email protected]8e937c1e2012-06-28 22:57:30278 // BeforeRun and AfterRun directly.
279 friend class base::MessagePumpForUI;
280#endif
281
[email protected]feb727e2012-07-13 11:02:57282#if defined(OS_IOS)
Gabriel Charettee2b632b2017-08-02 03:52:16283 // iOS doesn't support the blocking RunLoop::Run, so it calls
[email protected]feb727e2012-07-13 11:02:57284 // BeforeRun directly.
285 friend class base::MessagePumpUIApplication;
286#endif
287
[email protected]8e937c1e2012-06-28 22:57:30288 // Return false to abort the Run.
289 bool BeforeRun();
290 void AfterRun();
291
gab980a52712017-05-18 16:20:16292 // A copy of RunLoop::Delegate for the thread driven by tis RunLoop for quick
293 // access without using TLS (also allows access to state from another sequence
294 // during Run(), ref. |sequence_checker_| below).
gab273551962017-05-18 06:01:10295 Delegate* delegate_;
[email protected]8e937c1e2012-06-28 22:57:30296
Gabriel Charette3ff403e2017-08-07 04:22:48297 const Type type_;
298
gabcf5e4ce2017-05-19 22:56:57299#if DCHECK_IS_ON()
gab7af9dc02017-05-05 13:38:54300 bool run_called_ = false;
gabcf5e4ce2017-05-19 22:56:57301#endif
302
gab7af9dc02017-05-05 13:38:54303 bool quit_called_ = false;
304 bool running_ = false;
Gabriel Charettee2b632b2017-08-02 03:52:16305 // Used to record that QuitWhenIdle() was called on this RunLoop, meaning that
306 // the Delegate should quit Run() once it becomes idle (it's responsible for
Gabriel Charettea3ec9612017-12-14 17:22:40307 // probing this state via ShouldQuitWhenIdle()). This state is stored here
308 // rather than pushed to Delegate to support nested RunLoops.
gab7af9dc02017-05-05 13:38:54309 bool quit_when_idle_received_ = false;
[email protected]8e937c1e2012-06-28 22:57:30310
gabcf5e4ce2017-05-19 22:56:57311 // RunLoop is not thread-safe. Its state/methods, unless marked as such, may
312 // not be accessed from any other sequence than the thread it was constructed
313 // on. Exception: RunLoop can be safely accessed from one other sequence (or
314 // single parallel task) during Run() -- e.g. to Quit() without having to
315 // plumb ThreatTaskRunnerHandle::Get() throughout a test to repost QuitClosure
316 // to origin thread.
gab980a52712017-05-18 16:20:16317 SEQUENCE_CHECKER(sequence_checker_);
ahest72c1b442016-12-09 20:40:38318
gabcf5e4ce2017-05-19 22:56:57319 const scoped_refptr<SingleThreadTaskRunner> origin_task_runner_;
320
[email protected]dcf10632013-10-08 19:23:33321 // WeakPtrFactory for QuitClosure safety.
322 base::WeakPtrFactory<RunLoop> weak_factory_;
323
[email protected]8e937c1e2012-06-28 22:57:30324 DISALLOW_COPY_AND_ASSIGN(RunLoop);
325};
326
327} // namespace base
328
329#endif // BASE_RUN_LOOP_H_