[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 | |
8 | #include "base/base_export.h" | ||||
9 | #include "base/callback.h" | ||||
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 10 | #include "base/macros.h" |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 11 | #include "base/memory/weak_ptr.h" |
[email protected] | 495cad9 | 2013-07-18 08:12:40 | [diff] [blame] | 12 | #include "base/message_loop/message_loop.h" |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 13 | #include "build/build_config.h" |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 14 | |
15 | namespace base { | ||||
16 | #if defined(OS_ANDROID) | ||||
17 | class MessagePumpForUI; | ||||
18 | #endif | ||||
19 | |||||
[email protected] | feb727e | 2012-07-13 11:02:57 | [diff] [blame] | 20 | #if defined(OS_IOS) |
21 | class MessagePumpUIApplication; | ||||
22 | #endif | ||||
23 | |||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 24 | // Helper class to Run a nested MessageLoop. Please do not use nested |
25 | // MessageLoops in production code! If you must, use this class instead of | ||||
26 | // calling MessageLoop::Run/Quit directly. RunLoop::Run can only be called once | ||||
27 | // per RunLoop lifetime. Create a RunLoop on the stack and call Run/Quit to run | ||||
28 | // a nested MessageLoop. | ||||
29 | class BASE_EXPORT RunLoop { | ||||
30 | public: | ||||
31 | RunLoop(); | ||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 32 | ~RunLoop(); |
33 | |||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 34 | // Run the current MessageLoop. This blocks until Quit is called. Before |
blundell | 69c2549 | 2016-02-04 08:10:45 | [diff] [blame] | 35 | // calling Run, be sure to grab the QuitClosure in order to stop the |
36 | // MessageLoop asynchronously. MessageLoop::QuitWhenIdle and QuitNow will also | ||||
37 | // trigger a return from Run, but those are deprecated. | ||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 38 | void Run(); |
39 | |||||
40 | // Run the current MessageLoop until it doesn't find any tasks or messages in | ||||
41 | // the queue (it goes idle). WARNING: This may never return! Only use this | ||||
42 | // when repeating tasks such as animated web pages have been shut down. | ||||
43 | void RunUntilIdle(); | ||||
44 | |||||
45 | bool running() const { return running_; } | ||||
46 | |||||
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 47 | // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an |
48 | // 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] | 49 | // |
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 50 | // There can be other nested RunLoops servicing the same task queue |
51 | // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit() | ||||
52 | // and QuitWhenIdle() can be called before, during or after Run(). If called | ||||
53 | // before Run(), Run() will return immediately when called. Calling Quit() or | ||||
54 | // QuitWhenIdle() after the RunLoop has already finished running has no | ||||
55 | // effect. | ||||
56 | // | ||||
57 | // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will | ||||
58 | // terminate the targetted message loop. If a nested message loop continues | ||||
59 | // running, the target may NEVER terminate. It is very easy to livelock (run | ||||
60 | // forever) in such a case. | ||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 61 | void Quit(); |
fdoray | a4f28ec | 2016-06-10 00:08:58 | [diff] [blame] | 62 | void QuitWhenIdle(); |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 63 | |
fdoray | a365860 | 2016-06-10 18:23:15 | [diff] [blame] | 64 | // Convenience methods to get a closure that safely calls Quit() or |
65 | // QuitWhenIdle() (has no effect if the RunLoop instance is gone). | ||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 66 | // |
67 | // Example: | ||||
68 | // RunLoop run_loop; | ||||
69 | // PostTask(run_loop.QuitClosure()); | ||||
70 | // run_loop.Run(); | ||||
71 | base::Closure QuitClosure(); | ||||
fdoray | a365860 | 2016-06-10 18:23:15 | [diff] [blame] | 72 | base::Closure QuitWhenIdleClosure(); |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 73 | |
74 | private: | ||||
[email protected] | cb4303a | 2013-05-04 13:57:01 | [diff] [blame] | 75 | friend class MessageLoop; |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 76 | #if defined(OS_ANDROID) |
77 | // Android doesn't support the blocking MessageLoop::Run, so it calls | ||||
78 | // BeforeRun and AfterRun directly. | ||||
79 | friend class base::MessagePumpForUI; | ||||
80 | #endif | ||||
81 | |||||
[email protected] | feb727e | 2012-07-13 11:02:57 | [diff] [blame] | 82 | #if defined(OS_IOS) |
83 | // iOS doesn't support the blocking MessageLoop::Run, so it calls | ||||
84 | // BeforeRun directly. | ||||
85 | friend class base::MessagePumpUIApplication; | ||||
86 | #endif | ||||
87 | |||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 88 | // Return false to abort the Run. |
89 | bool BeforeRun(); | ||||
90 | void AfterRun(); | ||||
91 | |||||
92 | MessageLoop* loop_; | ||||
93 | |||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 94 | // Parent RunLoop or NULL if this is the top-most RunLoop. |
95 | RunLoop* previous_run_loop_; | ||||
96 | |||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 97 | // Used to count how many nested Run() invocations are on the stack. |
98 | int run_depth_; | ||||
99 | |||||
100 | bool run_called_; | ||||
101 | bool quit_called_; | ||||
102 | bool running_; | ||||
103 | |||||
104 | // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning | ||||
105 | // that we should quit Run once it becomes idle. | ||||
106 | bool quit_when_idle_received_; | ||||
107 | |||||
[email protected] | dcf1063 | 2013-10-08 19:23:33 | [diff] [blame] | 108 | // WeakPtrFactory for QuitClosure safety. |
109 | base::WeakPtrFactory<RunLoop> weak_factory_; | ||||
110 | |||||
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 111 | DISALLOW_COPY_AND_ASSIGN(RunLoop); |
112 | }; | ||||
113 | |||||
114 | } // namespace base | ||||
115 | |||||
116 | #endif // BASE_RUN_LOOP_H_ |