blob: 2c1cde133b190c7d22e9072c0d3e06fed7ee4dcf [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]b9f12d8f2014-04-16 05:29:4920#if defined(OS_WIN)
[email protected]440e3572014-01-17 00:10:2921class MessagePumpDispatcher;
22#endif
23
[email protected]feb727e2012-07-13 11:02:5724#if defined(OS_IOS)
25class MessagePumpUIApplication;
26#endif
27
[email protected]8e937c1e2012-06-28 22:57:3028// 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.
33class BASE_EXPORT RunLoop {
34 public:
35 RunLoop();
[email protected]9a2e75d2014-04-05 15:24:0336#if defined(OS_WIN)
[email protected]440e3572014-01-17 00:10:2937 explicit RunLoop(MessagePumpDispatcher* dispatcher);
[email protected]8e937c1e2012-06-28 22:57:3038#endif
39 ~RunLoop();
40
[email protected]8e937c1e2012-06-28 22:57:3041 // Run the current MessageLoop. This blocks until Quit is called. Before
blundell69c25492016-02-04 08:10:4542 // 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]8e937c1e2012-06-28 22:57:3045 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]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]9a2e75d2014-04-05 15:24:0398#if defined(OS_WIN)
[email protected]440e3572014-01-17 00:10:2999 MessagePumpDispatcher* dispatcher_;
[email protected]8e937c1e2012-06-28 22:57:30100#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]dcf10632013-10-08 19:23:33113 // WeakPtrFactory for QuitClosure safety.
114 base::WeakPtrFactory<RunLoop> weak_factory_;
115
[email protected]8e937c1e2012-06-28 22:57:30116 DISALLOW_COPY_AND_ASSIGN(RunLoop);
117};
118
119} // namespace base
120
121#endif // BASE_RUN_LOOP_H_