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