[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 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_ |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 7 | |
Gabriel Charette | 1ef212b | 2017-12-03 12:47:21 | [diff] [blame] | 8 | #include <utility> |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 9 | #include <vector> |
| 10 | |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 11 | #include "base/base_export.h" |
| 12 | #include "base/callback.h" |
Brett Wilson | 1f07f20e | 2017-10-02 18:55:28 | [diff] [blame] | 13 | #include "base/containers/stack.h" |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 14 | #include "base/macros.h" |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 15 | #include "base/memory/ref_counted.h" |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 16 | #include "base/memory/weak_ptr.h" |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 17 | #include "base/observer_list.h" |
gab | 980a5271 | 2017-05-18 16:20:16 | [diff] [blame] | 18 | #include "base/sequence_checker.h" |
ahest | 72c1b44 | 2016-12-09 20:40:38 | [diff] [blame] | 19 | #include "base/threading/thread_checker.h" |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 20 | #include "build/build_config.h" |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 21 | |
| 22 | namespace base { |
| 23 | #if defined(OS_ANDROID) |
| 24 | class MessagePumpForUI; |
| 25 | #endif |
| 26 | |
[email protected] | feb727e | 2012-07-13 11:02:57 | [diff] [blame] | 27 | #if defined(OS_IOS) |
| 28 | class MessagePumpUIApplication; |
| 29 | #endif |
| 30 | |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 31 | class SingleThreadTaskRunner; |
| 32 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 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 |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 38 | // per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 39 | // a nested RunLoop but please do not use nested loops in production code! |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 40 | class BASE_EXPORT RunLoop { |
| 41 | public: |
Gabriel Charette | 3ff403e | 2017-08-07 04:22:48 | [diff] [blame] | 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. 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] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 72 | ~RunLoop(); |
| 73 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 74 | // Run the current RunLoop::Delegate. This blocks until Quit is called. Before |
blundell | 69c2549 | 2016-02-04 08:10:45 | [diff] [blame] | 75 | // calling Run, be sure to grab the QuitClosure in order to stop the |
Gabriel Charette | d9839bc | 2017-07-29 14:17:47 | [diff] [blame] | 76 | // RunLoop::Delegate asynchronously. |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 77 | void Run(); |
| 78 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 79 | // 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] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 83 | void RunUntilIdle(); |
| 84 | |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 85 | bool running() const { |
gab | 980a5271 | 2017-05-18 16:20:16 | [diff] [blame] | 86 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 87 | return running_; |
| 88 | } |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 89 | |
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 90 | // 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] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 92 | // |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 93 | // 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 Charette | d9839bc | 2017-07-29 14:17:47 | [diff] [blame] | 97 | // 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. |
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 102 | // |
| 103 | // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will |
Gabriel Charette | 3ff403e | 2017-08-07 04:22:48 | [diff] [blame] | 104 | // terminate the targetted message loop. If a nested RunLoop continues |
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 105 | // running, the target may NEVER terminate. It is very easy to livelock (run |
| 106 | // forever) in such a case. |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 107 | void Quit(); |
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 108 | void QuitWhenIdle(); |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 109 | |
fdoray | a365860 | 2016-06-10 18:23:15 | [diff] [blame] | 110 | // Convenience methods to get a closure that safely calls Quit() or |
| 111 | // QuitWhenIdle() (has no effect if the RunLoop instance is gone). |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 112 | // |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 113 | // 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] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 117 | // Example: |
| 118 | // RunLoop run_loop; |
| 119 | // PostTask(run_loop.QuitClosure()); |
| 120 | // run_loop.Run(); |
| 121 | base::Closure QuitClosure(); |
fdoray | a365860 | 2016-06-10 18:23:15 | [diff] [blame] | 122 | base::Closure QuitWhenIdleClosure(); |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 123 | |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 124 | // Returns true if there is an active RunLoop on this thread. |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 125 | // Safe to call before RegisterDelegateForCurrentThread(). |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 126 | 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. |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 130 | // Safe to call before RegisterDelegateForCurrentThread(). |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 131 | static bool IsNestedOnCurrentThread(); |
| 132 | |
Gabriel Charette | 3ff403e | 2017-08-07 04:22:48 | [diff] [blame] | 133 | // A NestingObserver is notified when a nested RunLoop begins. The observers |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 134 | // 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 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 154 | // A RunLoop::Delegate is a generic interface that allows RunLoop to be |
Gabriel Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 155 | // separate from the underlying implementation of the message loop for this |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 156 | // 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 Charette | 46c535d2 | 2017-12-03 12:14:01 | [diff] [blame] | 161 | public: |
Gabriel Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 162 | // 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 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 167 | Delegate(); |
Gabriel Charette | 1ef212b | 2017-12-03 12:47:21 | [diff] [blame] | 168 | virtual ~Delegate(); |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 169 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 170 | // 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 Charette | 3ff403e | 2017-08-07 04:22:48 | [diff] [blame] | 175 | // call should result in the topmost active Run() call returning. The only |
Gabriel Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 176 | // 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 Charette | b030a4a | 2017-10-26 01:04:40 | [diff] [blame] | 182 | virtual void Run(bool application_tasks_allowed) = 0; |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 183 | virtual void Quit() = 0; |
| 184 | |
Gabriel Charette | 3ff403e | 2017-08-07 04:22:48 | [diff] [blame] | 185 | // 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 Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 194 | 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 Charette | 46c535d2 | 2017-12-03 12:14:01 | [diff] [blame] | 199 | private: |
| 200 | // While the state is owned by the Delegate subclass, only RunLoop can use |
| 201 | // it. |
| 202 | friend class RunLoop; |
| 203 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 204 | // 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 Wilson | 1f07f20e | 2017-10-02 18:55:28 | [diff] [blame] | 207 | using RunLoopStack = base::stack<RunLoop*, std::vector<RunLoop*>>; |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 208 | |
| 209 | bool allow_nesting_ = true; |
| 210 | RunLoopStack active_run_loops_; |
| 211 | ObserverList<RunLoop::NestingObserver> nesting_observers_; |
| 212 | |
Gabriel Charette | a4497505 | 2017-08-21 23:14:04 | [diff] [blame] | 213 | #if DCHECK_IS_ON() |
| 214 | bool allow_running_for_testing_ = true; |
| 215 | #endif |
| 216 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 217 | // True once this Delegate is bound to a thread via |
| 218 | // RegisterDelegateForCurrentThread(). |
| 219 | bool bound_ = false; |
| 220 | |
Gabriel Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 221 | ShouldQuitWhenIdleCallback should_quit_when_idle_callback_; |
| 222 | |
gab | 980a5271 | 2017-05-18 16:20:16 | [diff] [blame] | 223 | // Thread-affine per its use of TLS. |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 224 | THREAD_CHECKER(bound_thread_checker_); |
| 225 | |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 226 | 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 Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 231 | // on forever bound to that thread (including its destruction). |
| 232 | static void RegisterDelegateForCurrentThread(Delegate* delegate); |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 233 | |
Gabriel Charette | 1ef212b | 2017-12-03 12:47:21 | [diff] [blame] | 234 | // Akin to RegisterDelegateForCurrentThread but overrides an existing Delegate |
Gabriel Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 235 | // (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 Charette | 1ef212b | 2017-12-03 12:47:21 | [diff] [blame] | 243 | |
Gabriel Charette | 0592c3a | 2017-07-26 12:02:04 | [diff] [blame] | 244 | // 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 Charette | a4497505 | 2017-08-21 23:14:04 | [diff] [blame] | 253 | // 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] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 275 | private: |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 276 | #if defined(OS_ANDROID) |
Gabriel Charette | e2b632b | 2017-08-02 03:52:16 | [diff] [blame] | 277 | // Android doesn't support the blocking RunLoop::Run, so it calls |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 278 | // BeforeRun and AfterRun directly. |
| 279 | friend class base::MessagePumpForUI; |
| 280 | #endif |
| 281 | |
[email protected] | feb727e | 2012-07-13 11:02:57 | [diff] [blame] | 282 | #if defined(OS_IOS) |
Gabriel Charette | e2b632b | 2017-08-02 03:52:16 | [diff] [blame] | 283 | // iOS doesn't support the blocking RunLoop::Run, so it calls |
[email protected] | feb727e | 2012-07-13 11:02:57 | [diff] [blame] | 284 | // BeforeRun directly. |
| 285 | friend class base::MessagePumpUIApplication; |
| 286 | #endif |
| 287 | |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 288 | // Return false to abort the Run. |
| 289 | bool BeforeRun(); |
| 290 | void AfterRun(); |
| 291 | |
gab | 980a5271 | 2017-05-18 16:20:16 | [diff] [blame] | 292 | // 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). |
gab | 27355196 | 2017-05-18 06:01:10 | [diff] [blame] | 295 | Delegate* delegate_; |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 296 | |
Gabriel Charette | 3ff403e | 2017-08-07 04:22:48 | [diff] [blame] | 297 | const Type type_; |
| 298 | |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 299 | #if DCHECK_IS_ON() |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 300 | bool run_called_ = false; |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 301 | #endif |
| 302 | |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 303 | bool quit_called_ = false; |
| 304 | bool running_ = false; |
Gabriel Charette | e2b632b | 2017-08-02 03:52:16 | [diff] [blame] | 305 | // 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 Charette | a3ec961 | 2017-12-14 17:22:40 | [diff] [blame^] | 307 | // probing this state via ShouldQuitWhenIdle()). This state is stored here |
| 308 | // rather than pushed to Delegate to support nested RunLoops. |
gab | 7af9dc0 | 2017-05-05 13:38:54 | [diff] [blame] | 309 | bool quit_when_idle_received_ = false; |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 310 | |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 311 | // 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. |
gab | 980a5271 | 2017-05-18 16:20:16 | [diff] [blame] | 317 | SEQUENCE_CHECKER(sequence_checker_); |
ahest | 72c1b44 | 2016-12-09 20:40:38 | [diff] [blame] | 318 | |
gab | cf5e4ce | 2017-05-19 22:56:57 | [diff] [blame] | 319 | const scoped_refptr<SingleThreadTaskRunner> origin_task_runner_; |
| 320 | |
[email protected] | dcf1063 | 2013-10-08 19:23:33 | [diff] [blame] | 321 | // WeakPtrFactory for QuitClosure safety. |
| 322 | base::WeakPtrFactory<RunLoop> weak_factory_; |
| 323 | |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 324 | DISALLOW_COPY_AND_ASSIGN(RunLoop); |
| 325 | }; |
| 326 | |
| 327 | } // namespace base |
| 328 | |
| 329 | #endif // BASE_RUN_LOOP_H_ |