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

Side by Side Diff: base/run_loop.h

Issue 2818533003: Make nesting/running states a RunLoop rather than a MessageLoop concept. (Closed)
Patch Set: fix compile 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 DCHECK(thread_checker_.CalledOnValidThread());
48 return running_;
49 }
47 50
48 // Quit() quits an earlier call to Run() immediately. QuitWhenIdle() quits an 51 // 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. 52 // earlier call to Run() when there aren't any tasks or messages in the queue.
50 // 53 //
51 // There can be other nested RunLoops servicing the same task queue 54 // There can be other nested RunLoops servicing the same task queue
52 // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit() 55 // (MessageLoop); Quitting one RunLoop has no bearing on the others. Quit()
53 // and QuitWhenIdle() can be called before, during or after Run(). If called 56 // and QuitWhenIdle() can be called before, during or after Run(). If called
54 // before Run(), Run() will return immediately when called. Calling Quit() or 57 // before Run(), Run() will return immediately when called. Calling Quit() or
55 // QuitWhenIdle() after the RunLoop has already finished running has no 58 // QuitWhenIdle() after the RunLoop has already finished running has no
56 // effect. 59 // effect.
57 // 60 //
58 // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will 61 // 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 62 // 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 63 // running, the target may NEVER terminate. It is very easy to livelock (run
61 // forever) in such a case. 64 // forever) in such a case.
62 void Quit(); 65 void Quit();
63 void QuitWhenIdle(); 66 void QuitWhenIdle();
64 67
65 // Convenience methods to get a closure that safely calls Quit() or 68 // Convenience methods to get a closure that safely calls Quit() or
66 // QuitWhenIdle() (has no effect if the RunLoop instance is gone). 69 // QuitWhenIdle() (has no effect if the RunLoop instance is gone).
67 // 70 //
68 // Example: 71 // Example:
69 // RunLoop run_loop; 72 // RunLoop run_loop;
70 // PostTask(run_loop.QuitClosure()); 73 // PostTask(run_loop.QuitClosure());
71 // run_loop.Run(); 74 // run_loop.Run();
72 base::Closure QuitClosure(); 75 base::Closure QuitClosure();
73 base::Closure QuitWhenIdleClosure(); 76 base::Closure QuitWhenIdleClosure();
74 77
78 // Returns true if there is an active RunLoop on this thread.
79 static bool IsRunningOnCurrentThread();
80
81 // Returns true if there is an active RunLoop on this thread and it's nested
82 // within another active RunLoop.
83 static bool IsNestedOnCurrentThread();
84
85 // A NestingObserver is notified when a nested run loop begins. The observers
86 // are notified before the current thread's RunLoop::Delegate::Run() is
87 // invoked and nested work begins.
88 class BASE_EXPORT NestingObserver {
89 public:
90 virtual void OnBeginNestedMessageLoop() = 0;
Sami 2017/04/20 10:13:22 nit: TODO to rename this to OnBeginNestedRunLoop (
gab 2017/04/20 14:21:18 Ah yes, missed that one, definitely doing it now,
danakj 2017/04/20 14:57:32 +1
gab 2017/04/20 16:22:02 Done.
91
92 protected:
danakj 2017/04/20 14:57:32 why protected
gab 2017/04/20 16:22:02 Copied as-is from MessageLoop::NestingObserver. I
93 virtual ~NestingObserver() = default;
94 };
95
96 static void AddNestingObserverOnCurrentThread(NestingObserver* observer);
97 static void RemoveNestingObserverOnCurrentThread(NestingObserver* observer);
98
99 // Returns true if nesting is allowed on this thread.
100 static bool IsNestingAllowedOnCurrentThread();
101
102 // Disallow nesting. After this is called, running a nested RunLoop or calling
103 // Add/RemoveNestingObserverOnCurrentThread() on this thread will crash.
104 static void DisallowNestingOnCurrentThread();
105
75 private: 106 private:
76 friend class MessageLoop; 107 friend class MessageLoop;
77 #if defined(OS_ANDROID) 108 #if defined(OS_ANDROID)
78 // Android doesn't support the blocking MessageLoop::Run, so it calls 109 // Android doesn't support the blocking MessageLoop::Run, so it calls
79 // BeforeRun and AfterRun directly. 110 // BeforeRun and AfterRun directly.
80 friend class base::MessagePumpForUI; 111 friend class base::MessagePumpForUI;
81 #endif 112 #endif
82 113
83 #if defined(OS_IOS) 114 #if defined(OS_IOS)
84 // iOS doesn't support the blocking MessageLoop::Run, so it calls 115 // iOS doesn't support the blocking MessageLoop::Run, so it calls
85 // BeforeRun directly. 116 // BeforeRun directly.
86 friend class base::MessagePumpUIApplication; 117 friend class base::MessagePumpUIApplication;
87 #endif 118 #endif
88 119
89 // Return false to abort the Run. 120 // Return false to abort the Run.
90 bool BeforeRun(); 121 bool BeforeRun();
91 void AfterRun(); 122 void AfterRun();
92 123
93 MessageLoop* loop_; 124 MessageLoop* loop_;
94 125
95 // Parent RunLoop or NULL if this is the top-most RunLoop. 126 bool run_called_ = false;
96 RunLoop* previous_run_loop_; 127 bool quit_called_ = false;
97 128 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 129
105 // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning 130 // Used to record that QuitWhenIdle() was called on the MessageLoop, meaning
106 // that we should quit Run once it becomes idle. 131 // that we should quit Run once it becomes idle.
107 bool quit_when_idle_received_; 132 bool quit_when_idle_received_ = false;
108 133
134 // RunLoop's non-static methods are affine to the thread it's running on.
109 base::ThreadChecker thread_checker_; 135 base::ThreadChecker thread_checker_;
110 136
111 // WeakPtrFactory for QuitClosure safety. 137 // WeakPtrFactory for QuitClosure safety.
112 base::WeakPtrFactory<RunLoop> weak_factory_; 138 base::WeakPtrFactory<RunLoop> weak_factory_;
113 139
114 DISALLOW_COPY_AND_ASSIGN(RunLoop); 140 DISALLOW_COPY_AND_ASSIGN(RunLoop);
115 }; 141 };
116 142
117 } // namespace base 143 } // namespace base
118 144
119 #endif // BASE_RUN_LOOP_H_ 145 #endif // BASE_RUN_LOOP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698