Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: base/run_loop.h

Issue 2818533003: Make nesting/running states a RunLoop rather than a MessageLoop concept. (Closed)
Patch Set: disable more checks Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_RUN_LOOP_H_ 5 #ifndef BASE_RUN_LOOP_H_
6 #define BASE_RUN_LOOP_H_ 6 #define BASE_RUN_LOOP_H_
7 7
8 #include "base/base_export.h" 8 #include "base/base_export.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 25 matching lines...) Expand all
36 // calling Run, be sure to grab the QuitClosure in order to stop the 36 // calling Run, be sure to grab the QuitClosure in order to stop the
37 // MessageLoop asynchronously. MessageLoop::QuitWhenIdle and QuitNow will also 37 // MessageLoop asynchronously. MessageLoop::QuitWhenIdle and QuitNow will also
38 // trigger a return from Run, but those are deprecated. 38 // trigger a return from Run, but those are deprecated.
39 void Run(); 39 void Run();
40 40
41 // Run the current MessageLoop until it doesn't find any tasks or messages in 41 // Run the current MessageLoop until it doesn't find any tasks or messages in
42 // the queue (it goes idle). WARNING: This may never return! Only use this 42 // the queue (it goes idle). WARNING: This may never return! Only use this
43 // when repeating tasks such as animated web pages have been shut down. 43 // when repeating tasks such as animated web pages have been shut down.
44 void RunUntilIdle(); 44 void RunUntilIdle();
45 45
46 bool running() const { return running_; } 46 bool running() const {
47 // TODO(gab): Fix bad usage of this API...
48 // DCHECK(thread_checker_.CalledOnValidThread());
49 return running_;
50 }
47 51
48 // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an 52 // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an
49 // earlier call to Run() when there aren't any tasks or messages in the queue. 53 // earlier call to Run() when there aren't any tasks or messages in the queue.
50 // 54 //
51 // There can be other nested RunLoops servicing the same task queue 55 // There can be other nested RunLoops servicing the same task queue
52 // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit() 56 // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit()
53 // and QuitWhenIdle() can be called before, during or after Run(). If called 57 // and QuitWhenIdle() can be called before, during or after Run(). If called
54 // before Run(), Run() will return immediately when called. Calling Quit() or 58 // before Run(), Run() will return immediately when called. Calling Quit() or
55 // QuitWhenIdle() after the RunLoop has already finished running has no 59 // QuitWhenIdle() after the RunLoop has already finished running has no
56 // effect. 60 // effect.
57 // 61 //
58 // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will 62 // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will
59 // terminate the targetted message loop. If a nested message loop continues 63 // terminate the targetted message loop. If a nested message loop continues
60 // running, the target may NEVER terminate. It is very easy to livelock (run 64 // running, the target may NEVER terminate. It is very easy to livelock (run
61 // forever) in such a case. 65 // forever) in such a case.
62 void Quit(); 66 void Quit();
63 void QuitWhenIdle(); 67 void QuitWhenIdle();
64 68
65 // Convenience methods to get a closure that safely calls Quit() or 69 // Convenience methods to get a closure that safely calls Quit() or
66 // QuitWhenIdle() (has no effect if the RunLoop instance is gone). 70 // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
67 // 71 //
68 // Example: 72 // Example:
69 // RunLoop run_loop; 73 // RunLoop run_loop;
70 // PostTask(run_loop.QuitClosure()); 74 // PostTask(run_loop.QuitClosure());
71 // run_loop.Run(); 75 // run_loop.Run();
72 base::Closure QuitClosure(); 76 base::Closure QuitClosure();
73 base::Closure QuitWhenIdleClosure(); 77 base::Closure QuitWhenIdleClosure();
74 78
79 // Returns true if there is an active RunLoop on this thread.
80 static bool IsRunningOnCurrentThread();
81
82 // Returns true if there is an active RunLoop on this thread and it's nested
83 // within another active RunLoop.
84 static bool IsNestedOnCurrentThread();
85
86 // A NestingObserver is notified when a nested run loop begins. The observers
87 // are notified before the current thread's RunLoop::Delegate::Run() is
88 // invoked and nested work begins.
89 class BASE_EXPORT NestingObserver {
90 public:
91 virtual void OnBeginNestedRunLoop() = 0;
92
93 protected:
94 virtual ~NestingObserver() = default;
95 };
96
97 static void AddNestingObserverOnCurrentThread(NestingObserver* observer);
98 static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer);
99
100 // Returns true if nesting is allowed on this thread.
101 static bool IsNestingAllowedOnCurrentThread();
102
103 // Disallow nesting. After this is called, running a nested RunLoop or calling
104 // Add/RemoveNestingObserverOnCurrentThread() on this thread will crash.
105 static void DisallowNestingOnCurrentThread();
106
75 private: 107 private:
76 friend class MessageLoop; 108 friend class MessageLoop;
77 #if defined(OS_ANDROID) 109 #if defined(OS_ANDROID)
78 // Android doesn't support the blocking MessageLoop::Run, so it calls 110 // Android doesn't support the blocking MessageLoop::Run, so it calls
79 // BeforeRun and AfterRun directly. 111 // BeforeRun and AfterRun directly.
80 friend class base::MessagePumpForUI; 112 friend class base::MessagePumpForUI;
81 #endif 113 #endif
82 114
83 #if defined(OS_IOS) 115 #if defined(OS_IOS)
84 // iOS doesn't support the blocking MessageLoop::Run, so it calls 116 // iOS doesn't support the blocking MessageLoop::Run, so it calls
85 // BeforeRun directly. 117 // BeforeRun directly.
86 friend class base::MessagePumpUIApplication; 118 friend class base::MessagePumpUIApplication;
87 #endif 119 #endif
88 120
89 // Return false to abort the Run. 121 // Return false to abort the Run.
90 bool BeforeRun(); 122 bool BeforeRun();
91 void AfterRun(); 123 void AfterRun();
92 124
93 MessageLoop* loop_; 125 MessageLoop* loop_;
94 126
95 // Parent RunLoop or NULL if this is the top-most RunLoop. 127 bool run_called_ = false;
96 RunLoop* previous_run_loop_; 128 bool quit_called_ = false;
97 129 bool running_ = false;
98 // Used to count how many nested Run() invocations are on the stack.
99 int run_depth_;
100
101 bool run_called_;
102 bool quit_called_;
103 bool running_;
104 130
105 // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning 131 // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning
106 // that we should quit Run once it becomes idle. 132 // that we should quit Run once it becomes idle.
107 bool quit_when_idle_received_; 133 bool quit_when_idle_received_ = false;
108 134
135 // RunLoop's non-static methods are affine to the thread it's running on.
109 base::ThreadChecker thread_checker_; 136 base::ThreadChecker thread_checker_;
110 137
111 // WeakPtrFactory for QuitClosure safety. 138 // WeakPtrFactory for QuitClosure safety.
112 base::WeakPtrFactory<RunLoop> weak_factory_; 139 base::WeakPtrFactory<RunLoop> weak_factory_;
113 140
114 DISALLOW_COPY_AND_ASSIGN(RunLoop); 141 DISALLOW_COPY_AND_ASSIGN(RunLoop);
115 }; 142 };
116 143
117 } // namespace base 144 } // namespace base
118 145
119 #endif // BASE_RUN_LOOP_H_ 146 #endif // BASE_RUN_LOOP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698