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