blob: 077d097ba9a2a35c6ec51d017f588b9f195e48c0 [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
8#include "base/base_export.h"
9#include "base/callback.h"
avi9b6f42932015-12-26 22:15:1410#include "base/macros.h"
[email protected]8e937c1e2012-06-28 22:57:3011#include "base/memory/weak_ptr.h"
[email protected]495cad92013-07-18 08:12:4012#include "base/message_loop/message_loop.h"
ahest72c1b442016-12-09 20:40:3813#include "base/threading/thread_checker.h"
avi9b6f42932015-12-26 22:15:1414#include "build/build_config.h"
[email protected]8e937c1e2012-06-28 22:57:3015
16namespace base {
17#if defined(OS_ANDROID)
18class MessagePumpForUI;
19#endif
20
[email protected]feb727e2012-07-13 11:02:5721#if defined(OS_IOS)
22class MessagePumpUIApplication;
23#endif
24
[email protected]8e937c1e2012-06-28 22:57:3025// Helper class to Run a nested MessageLoop. Please do not use nested
26// MessageLoops in production code! If you must, use this class instead of
27// calling MessageLoop::Run/Quit directly. RunLoop::Run can only be called once
28// per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run
29// a nested MessageLoop.
30class BASE_EXPORT RunLoop {
31 public:
32 RunLoop();
[email protected]8e937c1e2012-06-28 22:57:3033 ~RunLoop();
34
[email protected]8e937c1e2012-06-28 22:57:3035 // Run the current MessageLoop. This blocks until Quit is called. Before
blundell69c25492016-02-04 08:10:4536 // calling Run, be sure to grab the QuitClosure in order to stop the
37 // MessageLoop asynchronously. MessageLoop::QuitWhenIdle and QuitNow will also
38 // trigger a return from Run, but those are deprecated.
[email protected]8e937c1e2012-06-28 22:57:3039 void Run();
40
41 // Run the current MessageLoop until it doesn't find any tasks or messages in
42 // the queue (it goes idle). WARNING: This may never return! Only use this
43 // when repeating tasks such as animated web pages have been shut down.
44 void RunUntilIdle();
45
46 bool running() const { return running_; }
47
fdoraya4f28ec2016-06-10 00:08:5848 // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an
49 // earlier call to Run() when there aren't any tasks or messages in the queue.
[email protected]8e937c1e2012-06-28 22:57:3050 //
fdoraya4f28ec2016-06-10 00:08:5851 // There can be other nested RunLoops servicing the same task queue
52 // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit()
53 // and QuitWhenIdle() can be called before, during or after Run(). If called
54 // before Run(), Run() will return immediately when called. Calling Quit() or
55 // QuitWhenIdle() after the RunLoop has already finished running has no
56 // effect.
57 //
58 // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will
59 // terminate the targetted message loop. If a nested message loop continues
60 // running, the target may NEVER terminate. It is very easy to livelock (run
61 // forever) in such a case.
[email protected]8e937c1e2012-06-28 22:57:3062 void Quit();
fdoraya4f28ec2016-06-10 00:08:5863 void QuitWhenIdle();
[email protected]8e937c1e2012-06-28 22:57:3064
fdoraya3658602016-06-10 18:23:1565 // Convenience methods to get a closure that safely calls Quit() or
66 // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
[email protected]8e937c1e2012-06-28 22:57:3067 //
68 // Example:
69 // RunLoop run_loop;
70 // PostTask(run_loop.QuitClosure());
71 // run_loop.Run();
72 base::Closure QuitClosure();
fdoraya3658602016-06-10 18:23:1573 base::Closure QuitWhenIdleClosure();
[email protected]8e937c1e2012-06-28 22:57:3074
75 private:
[email protected]cb4303a2013-05-04 13:57:0176 friend class MessageLoop;
[email protected]8e937c1e2012-06-28 22:57:3077#if defined(OS_ANDROID)
78 // Android doesn't support the blocking MessageLoop::Run, so it calls
79 // BeforeRun and AfterRun directly.
80 friend class base::MessagePumpForUI;
81#endif
82
[email protected]feb727e2012-07-13 11:02:5783#if defined(OS_IOS)
84 // iOS doesn't support the blocking MessageLoop::Run, so it calls
85 // BeforeRun directly.
86 friend class base::MessagePumpUIApplication;
87#endif
88
[email protected]8e937c1e2012-06-28 22:57:3089 // Return false to abort the Run.
90 bool BeforeRun();
91 void AfterRun();
92
93 MessageLoop* loop_;
94
[email protected]8e937c1e2012-06-28 22:57:3095 // Parent RunLoop or NULL if this is the top-most RunLoop.
96 RunLoop* previous_run_loop_;
97
[email protected]8e937c1e2012-06-28 22:57:3098 // Used to count how many nested Run() invocations are on the stack.
99 int run_depth_;
100
101 bool run_called_;
102 bool quit_called_;
103 bool running_;
104
105 // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning
106 // that we should quit Run once it becomes idle.
107 bool quit_when_idle_received_;
108
ahest72c1b442016-12-09 20:40:38109 base::ThreadChecker thread_checker_;
110
[email protected]dcf10632013-10-08 19:23:33111 // WeakPtrFactory for QuitClosure safety.
112 base::WeakPtrFactory<RunLoop> weak_factory_;
113
[email protected]8e937c1e2012-06-28 22:57:30114 DISALLOW_COPY_AND_ASSIGN(RunLoop);
115};
116
117} // namespace base
118
119#endif // BASE_RUN_LOOP_H_