blob: 635018f434ec1a69c331366d80506ab2dc6a2ce0 [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"
avi9b6f42932015-12-26 22:15:1413#include "build/build_config.h"
[email protected]8e937c1e2012-06-28 22:57:3014
15namespace base {
16#if defined(OS_ANDROID)
17class MessagePumpForUI;
18#endif
19
[email protected]feb727e2012-07-13 11:02:5720#if defined(OS_IOS)
21class MessagePumpUIApplication;
22#endif
23
[email protected]8e937c1e2012-06-28 22:57:3024// 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.
29class BASE_EXPORT RunLoop {
30 public:
31 RunLoop();
[email protected]8e937c1e2012-06-28 22:57:3032 ~RunLoop();
33
[email protected]8e937c1e2012-06-28 22:57:3034 // Run the current MessageLoop. This blocks until Quit is called. Before
blundell69c25492016-02-04 08:10:4535 // 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]8e937c1e2012-06-28 22:57:3038 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
fdoraya4f28ec2016-06-10 00:08:5847 // 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]8e937c1e2012-06-28 22:57:3049 //
fdoraya4f28ec2016-06-10 00:08:5850 // 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]8e937c1e2012-06-28 22:57:3061 void Quit();
fdoraya4f28ec2016-06-10 00:08:5862 void QuitWhenIdle();
[email protected]8e937c1e2012-06-28 22:57:3063
fdoraya3658602016-06-10 18:23:1564 // Convenience methods to get a closure that safely calls Quit() or
65 // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
[email protected]8e937c1e2012-06-28 22:57:3066 //
67 // Example:
68 // RunLoop run_loop;
69 // PostTask(run_loop.QuitClosure());
70 // run_loop.Run();
71 base::Closure QuitClosure();
fdoraya3658602016-06-10 18:23:1572 base::Closure QuitWhenIdleClosure();
[email protected]8e937c1e2012-06-28 22:57:3073
74 private:
[email protected]cb4303a2013-05-04 13:57:0175 friend class MessageLoop;
[email protected]8e937c1e2012-06-28 22:57:3076#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]feb727e2012-07-13 11:02:5782#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]8e937c1e2012-06-28 22:57:3088 // Return false to abort the Run.
89 bool BeforeRun();
90 void AfterRun();
91
92 MessageLoop* loop_;
93
[email protected]8e937c1e2012-06-28 22:57:3094 // Parent RunLoop or NULL if this is the top-most RunLoop.
95 RunLoop* previous_run_loop_;
96
[email protected]8e937c1e2012-06-28 22:57:3097 // 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]dcf10632013-10-08 19:23:33108 // WeakPtrFactory for QuitClosure safety.
109 base::WeakPtrFactory<RunLoop> weak_factory_;
110
[email protected]8e937c1e2012-06-28 22:57:30111 DISALLOW_COPY_AND_ASSIGN(RunLoop);
112};
113
114} // namespace base
115
116#endif // BASE_RUN_LOOP_H_