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

Side by Side Diff: base/message_pump_mac.mm

Issue 146006: Fire off work in outer run loops when inner loops exit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « base/message_pump_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 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 #include "base/message_pump_mac.h" 5 #include "base/message_pump_mac.h"
6 6
7 #import <AppKit/AppKit.h> 7 #import <AppKit/AppKit.h>
8 #import <Foundation/Foundation.h> 8 #import <Foundation/Foundation.h>
9 #include <float.h> 9 #include <float.h>
10 10
11 #include "base/scoped_nsautorelease_pool.h" 11 #include "base/scoped_nsautorelease_pool.h"
12 #include "base/time.h" 12 #include "base/time.h"
13 13
14 namespace { 14 namespace {
15 15
16 void NoOp(void* info) { 16 void NoOp(void* info) {
17 } 17 }
18 18
19 } // namespace 19 } // namespace
20 20
21 namespace base { 21 namespace base {
22 22
23 // Must be called on the run loop thread. 23 // Must be called on the run loop thread.
24 MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase() 24 MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
25 : delegate_(NULL) { 25 : nesting_level_(0),
26 delegate_(NULL)
27 {
26 run_loop_ = CFRunLoopGetCurrent(); 28 run_loop_ = CFRunLoopGetCurrent();
27 CFRetain(run_loop_); 29 CFRetain(run_loop_);
28 30
29 // Set a repeating timer with a preposterous firing time and interval. The 31 // Set a repeating timer with a preposterous firing time and interval. The
30 // timer will effectively never fire as-is. The firing time will be adjusted 32 // timer will effectively never fire as-is. The firing time will be adjusted
31 // as needed when ScheduleDelayedWork is called. 33 // as needed when ScheduleDelayedWork is called.
32 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext(); 34 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
33 timer_context.info = this; 35 timer_context.info = this;
34 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator 36 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator
35 DBL_MAX, // fire time 37 DBL_MAX, // fire time
36 DBL_MAX, // interval 38 DBL_MAX, // interval
37 0, // flags (ignored) 39 0, // flags (ignored)
38 0, // priority (ignored) 40 0, // priority (ignored)
39 RunDelayedWorkTimer, 41 RunDelayedWorkTimer,
40 &timer_context); 42 &timer_context);
41 CFRunLoopAddTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes); 43 CFRunLoopAddTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes);
42 44
43 CFRunLoopSourceContext source_context = CFRunLoopSourceContext(); 45 CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
44 source_context.info = this; 46 source_context.info = this;
45 source_context.perform = RunWork; 47 source_context.perform = RunWorkSource;
46 work_source_ = CFRunLoopSourceCreate(NULL, // allocator 48 work_source_ = CFRunLoopSourceCreate(NULL, // allocator
47 0, // priority 49 1, // priority
48 &source_context); 50 &source_context);
49 CFRunLoopAddSource(run_loop_, work_source_, kCFRunLoopCommonModes); 51 CFRunLoopAddSource(run_loop_, work_source_, kCFRunLoopCommonModes);
50 52
51 source_context.perform = RunDelayedWork; 53 source_context.perform = RunDelayedWorkSource;
52 delayed_work_source_ = CFRunLoopSourceCreate(NULL, // allocator 54 delayed_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
53 1, // priority 55 2, // priority
54 &source_context); 56 &source_context);
55 CFRunLoopAddSource(run_loop_, delayed_work_source_, kCFRunLoopCommonModes); 57 CFRunLoopAddSource(run_loop_, delayed_work_source_, kCFRunLoopCommonModes);
56 58
59 source_context.perform = RunIdleWorkSource;
60 idle_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
61 3, // priority
62 &source_context);
63 CFRunLoopAddSource(run_loop_, idle_work_source_, kCFRunLoopCommonModes);
64
65 source_context.perform = RunNestingDeferredWorkSource;
66 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
67 0, // priority
68 &source_context);
69 CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_,
70 kCFRunLoopCommonModes);
71
57 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext(); 72 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
58 observer_context.info = this; 73 observer_context.info = this;
59 idle_work_observer_ = CFRunLoopObserverCreate(NULL, // allocator 74 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator
60 kCFRunLoopBeforeWaiting, 75 kCFRunLoopBeforeWaiting,
61 true, // repeat 76 true, // repeat
62 0, // priority 77 0, // priority
63 RunIdleWork, 78 PreWaitObserver,
64 &observer_context); 79 &observer_context);
65 CFRunLoopAddObserver(run_loop_, idle_work_observer_, kCFRunLoopCommonModes); 80 CFRunLoopAddObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes);
81
82 enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator
83 kCFRunLoopEntry |
84 kCFRunLoopExit,
85 true, // repeat
86 0, // priority
87 EnterExitObserver,
88 &observer_context);
89 CFRunLoopAddObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
66 } 90 }
67 91
68 // Ideally called on the run loop thread. 92 // Ideally called on the run loop thread. If other run loops were running
93 // lower on the run loop thread's stack when this object was created, the
94 // same number of run loops must be running when this object is destroyed.
69 MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() { 95 MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() {
70 CFRunLoopRemoveObserver(run_loop_, idle_work_observer_, 96 CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_,
71 kCFRunLoopCommonModes); 97 kCFRunLoopCommonModes);
72 CFRelease(idle_work_observer_); 98 CFRelease(enter_exit_observer_);
99
100 CFRunLoopRemoveObserver(run_loop_, pre_wait_observer_,
101 kCFRunLoopCommonModes);
102 CFRelease(pre_wait_observer_);
103
104 CFRunLoopRemoveSource(run_loop_, nesting_deferred_work_source_,
105 kCFRunLoopCommonModes);
106 CFRelease(nesting_deferred_work_source_);
107
108 CFRunLoopRemoveSource(run_loop_, idle_work_source_, kCFRunLoopCommonModes);
109 CFRelease(idle_work_source_);
73 110
74 CFRunLoopRemoveSource(run_loop_, delayed_work_source_, kCFRunLoopCommonModes); 111 CFRunLoopRemoveSource(run_loop_, delayed_work_source_, kCFRunLoopCommonModes);
75 CFRelease(delayed_work_source_); 112 CFRelease(delayed_work_source_);
76 113
77 CFRunLoopRemoveSource(run_loop_, work_source_, kCFRunLoopCommonModes); 114 CFRunLoopRemoveSource(run_loop_, work_source_, kCFRunLoopCommonModes);
78 CFRelease(work_source_); 115 CFRelease(work_source_);
79 116
80 CFRunLoopRemoveTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes); 117 CFRunLoopRemoveTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes);
81 CFRelease(delayed_work_timer_); 118 CFRelease(delayed_work_timer_);
82 119
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 }; 155 };
119 CFAbsoluteTime fire_time = CFGregorianDateGetAbsoluteTime(gregorian, NULL); 156 CFAbsoluteTime fire_time = CFGregorianDateGetAbsoluteTime(gregorian, NULL);
120 157
121 CFRunLoopTimerSetNextFireDate(delayed_work_timer_, fire_time); 158 CFRunLoopTimerSetNextFireDate(delayed_work_timer_, fire_time);
122 } 159 }
123 160
124 // Called from the run loop. 161 // Called from the run loop.
125 // static 162 // static
126 void MessagePumpCFRunLoopBase::RunDelayedWorkTimer(CFRunLoopTimerRef timer, 163 void MessagePumpCFRunLoopBase::RunDelayedWorkTimer(CFRunLoopTimerRef timer,
127 void* info) { 164 void* info) {
128 MessagePumpCFRunLoop* self = static_cast<MessagePumpCFRunLoop*>(info); 165 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
129 166
130 // CFRunLoopTimers fire outside of the priority scheme for CFRunLoopSources. 167 // CFRunLoopTimers fire outside of the priority scheme for CFRunLoopSources.
131 // In order to establish the proper priority where delegate_->DoDelayedWork 168 // In order to establish the proper priority where delegate_->DoDelayedWork
132 // can only be called if delegate_->DoWork returns false, the timer used 169 // can only be called if delegate_->DoWork returns false, the timer used
133 // to schedule delayed work must signal a CFRunLoopSource set at a lower 170 // to schedule delayed work must signal a CFRunLoopSource set at a lower
134 // priority than the one used for delegate_->DoWork. 171 // priority than the one used for delegate_->DoWork.
135 CFRunLoopSourceSignal(self->delayed_work_source_); 172 CFRunLoopSourceSignal(self->delayed_work_source_);
136 } 173 }
137 174
138 // Called from the run loop. 175 // Called from the run loop.
139 // static 176 // static
140 void MessagePumpCFRunLoopBase::RunWork(void* info) { 177 void MessagePumpCFRunLoopBase::RunWorkSource(void* info) {
141 MessagePumpCFRunLoop* self = static_cast<MessagePumpCFRunLoop*>(info); 178 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
179 self->RunWork();
180 }
142 181
182 // Called by MessagePumpCFRunLoopBase::RunWorkSource.
183 bool MessagePumpCFRunLoopBase::RunWork() {
143 // If we're on the main event loop, the NSApp runloop won't clean up the 184 // If we're on the main event loop, the NSApp runloop won't clean up the
144 // autoreleasepool until there is UI event, so use a local one for any 185 // autorelease pool until there is a UI event, so use a local one for any
145 // autoreleased objects to ensure they go away sooner. 186 // autoreleased objects to ensure they go away sooner.
146 ScopedNSAutoreleasePool autorelease_pool; 187 ScopedNSAutoreleasePool autorelease_pool;
147 188
148 // Call DoWork once, and if something was done, arrange to come back here 189 // Call DoWork once, and if something was done, arrange to come back here
149 // again as long as the loop is still running. 190 // again as long as the loop is still running.
150 if (self->delegate_->DoWork()) { 191 bool did_work = delegate_->DoWork();
151 CFRunLoopSourceSignal(self->work_source_); 192 if (did_work) {
193 CFRunLoopSourceSignal(work_source_);
152 } 194 }
195
196 return did_work;
153 } 197 }
154 198
155 // Called from the run loop. 199 // Called from the run loop.
156 // static 200 // static
157 void MessagePumpCFRunLoopBase::RunDelayedWork(void* info) { 201 void MessagePumpCFRunLoopBase::RunDelayedWorkSource(void* info) {
158 MessagePumpCFRunLoop* self = static_cast<MessagePumpCFRunLoop*>(info); 202 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
203 self->RunDelayedWork();
204 }
159 205
206 // Called by MessagePumpCFRunLoopBase::RunDelayedWorkSource.
207 bool MessagePumpCFRunLoopBase::RunDelayedWork() {
160 // If we're on the main event loop, the NSApp runloop won't clean up the 208 // If we're on the main event loop, the NSApp runloop won't clean up the
161 // autoreleasepool until there is UI event, so use a local one for any 209 // autorelease pool until there is a UI event, so use a local one for any
162 // autoreleased objects to ensure they go away sooner. 210 // autoreleased objects to ensure they go away sooner.
163 ScopedNSAutoreleasePool autorelease_pool; 211 ScopedNSAutoreleasePool autorelease_pool;
164 212
165 Time next_time; 213 Time next_time;
166 self->delegate_->DoDelayedWork(&next_time); 214 delegate_->DoDelayedWork(&next_time);
167 if (!next_time.is_null()) { 215
216 bool more_work = !next_time.is_null();
217 if (more_work) {
168 TimeDelta delay = next_time - Time::Now(); 218 TimeDelta delay = next_time - Time::Now();
169 if (delay > TimeDelta()) { 219 if (delay > TimeDelta()) {
170 // There's more delayed work to be done in the future. 220 // There's more delayed work to be done in the future.
171 self->ScheduleDelayedWork(next_time); 221 ScheduleDelayedWork(next_time);
172 } else { 222 } else {
173 // There's more delayed work to be done, and its time is in the past. 223 // There's more delayed work to be done, and its time is in the past.
174 // Arrange to come back here directly as long as the loop is still 224 // Arrange to come back here directly as long as the loop is still
175 // running. 225 // running.
176 CFRunLoopSourceSignal(self->delayed_work_source_); 226 CFRunLoopSourceSignal(delayed_work_source_);
177 } 227 }
178 } 228 }
229
230 return more_work;
179 } 231 }
180 232
181 // Called from the run loop. 233 // Called from the run loop.
182 // static 234 // static
183 void MessagePumpCFRunLoopBase::RunIdleWork(CFRunLoopObserverRef observer, 235 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) {
184 CFRunLoopActivity activity, 236 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
185 void* info) { 237 self->RunIdleWork();
186 MessagePumpCFRunLoop* self = static_cast<MessagePumpCFRunLoop*>(info); 238 }
187 239
240 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource.
241 bool MessagePumpCFRunLoopBase::RunIdleWork() {
188 // If we're on the main event loop, the NSApp runloop won't clean up the 242 // If we're on the main event loop, the NSApp runloop won't clean up the
189 // autoreleasepool until there is UI event, so use a local one for any 243 // autorelease pool until there is a UI event, so use a local one for any
190 // autoreleased objects to ensure they go away sooner. 244 // autoreleased objects to ensure they go away sooner.
191 ScopedNSAutoreleasePool autorelease_pool; 245 ScopedNSAutoreleasePool autorelease_pool;
192 246
193 // The "self->delegate_ &&" part of the clause is needed for the case of 247 // Call DoIdleWork once, and if something was done, arrange to come back here
194 // the temporary modal first run dialog. The dialog is displayed really 248 // again as long as the loop is still running.
195 // early in the Chrome launch process at which time self->delegate_ is null. 249 bool did_work = delegate_->DoIdleWork();
196 // TODO: remove the "self->delegate_ &&" clause from the bellow condition once 250 if (did_work) {
197 // we remove the modal first run dialog. 251 CFRunLoopSourceSignal(idle_work_source_);
198 if (self->delegate_ && self->delegate_->DoIdleWork()) {
199 // If idle work was done, don't let the loop go to sleep. More idle work
200 // might be waiting.
201 CFRunLoopWakeUp(self->run_loop_);
202 } 252 }
253
254 return did_work;
203 } 255 }
204 256
205 // Must be called on the run loop thread. 257 // Called from the run loop.
206 MessagePumpCFRunLoop::MessagePumpCFRunLoop() 258 // static
207 : nesting_level_(0), 259 void MessagePumpCFRunLoopBase::RunNestingDeferredWorkSource(void* info) {
208 innermost_quittable_(0), 260 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
209 quit_pending_(false) { 261 self->RunNestingDeferredWork();
210 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
211 observer_context.info = this;
212 enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator
213 kCFRunLoopEntry |
214 kCFRunLoopExit,
215 true, // repeat
216 0, // priority
217 EnterExitRunLoop,
218 &observer_context);
219 CFRunLoopAddObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
220 } 262 }
221 263
222 // Ideally called on the run loop thread. If other CFRunLoopRun loops were 264 // Called by MessagePumpCFRunLoopBase::RunNestingDeferredWorkSource.
223 // running lower on the run loop thread's stack when this object was created, 265 bool MessagePumpCFRunLoopBase::RunNestingDeferredWork() {
224 // the same number of CFRunLoopRun loops must be running when this object is 266 if (!RunWork()) {
225 // destroyed. 267 if (!RunDelayedWork()) {
226 MessagePumpCFRunLoop::~MessagePumpCFRunLoop() { 268 if (!RunIdleWork()) {
227 CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_, 269 return false;
228 kCFRunLoopCommonModes); 270 }
229 CFRelease(enter_exit_observer_); 271 }
272 }
273
274 return true;
230 } 275 }
231 276
232 // Called by CFRunLoopBase::DoRun. If other CFRunLoopRun loops were running 277 // Called from the run loop.
233 // lower on the run loop thread's stack when this object was created, the same 278 // static
234 // number of CFRunLoopRun loops must be running for the outermost call to Run. 279 void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
235 // Run/DoRun are reentrant after that point. 280 CFRunLoopActivity activity,
281 void* info) {
282 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
283
284 // Attempt to do some idle work before going to sleep.
285 self->RunIdleWork();
286 }
287
288 // Called from the run loop.
289 // static
290 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
291 CFRunLoopActivity activity,
292 void* info) {
293 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
294
295 switch (activity) {
296 case kCFRunLoopEntry:
297 ++self->nesting_level_;
298 break;
299 case kCFRunLoopExit:
300 --self->nesting_level_;
301 if (self->nesting_level_) {
302 // It's possible that some work was not performed because it was
303 // inappropriate to do within a nested loop. When leaving any inner
304 // loop, signal the nesting-deferred work source to ensure that such
305 // work be afforded an opportunity to be processed if appropriate.
306 CFRunLoopSourceSignal(self->nesting_deferred_work_source_);
307 }
308 break;
309 default:
310 break;
311 }
312
313 self->EnterExitRunLoop(activity);
314 }
315
316 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default
317 // implementation is a no-op.
318 void MessagePumpCFRunLoopBase::EnterExitRunLoop(CFRunLoopActivity activity) {
319 }
320
321 MessagePumpCFRunLoop::MessagePumpCFRunLoop()
322 : innermost_quittable_(0),
323 quit_pending_(false) {
324 }
325
326 // Called by MessagePumpCFRunLoopBase::DoRun. If other CFRunLoopRun loops were
327 // running lower on the run loop thread's stack when this object was created,
328 // the same number of CFRunLoopRun loops must be running for the outermost call
329 // to Run. Run/DoRun are reentrant after that point.
236 void MessagePumpCFRunLoop::DoRun(Delegate* delegate) { 330 void MessagePumpCFRunLoop::DoRun(Delegate* delegate) {
237 // nesting_level_ will be incremented in EnterExitRunLoop, so set 331 // nesting_level_ will be incremented in EnterExitRunLoop, so set
238 // innermost_quittable_ accordingly. 332 // innermost_quittable_ accordingly.
239 int last_innermost_quittable = innermost_quittable_; 333 int last_innermost_quittable = innermost_quittable_;
240 innermost_quittable_ = nesting_level_ + 1; 334 innermost_quittable_ = nesting_level_ + 1;
241 335
242 // This is completely identical to calling CFRunLoopRun(), except autorelease 336 // This is completely identical to calling CFRunLoopRun(), except autorelease
243 // pool management is introduced. 337 // pool management is introduced.
244 int result; 338 int result;
245 do { 339 do {
(...skipping 14 matching lines...) Expand all
260 } else { 354 } else {
261 // There's another loop running inside the loop managed by this object. 355 // There's another loop running inside the loop managed by this object.
262 // In other words, someone else called CFRunLoopRun on the same thread, 356 // In other words, someone else called CFRunLoopRun on the same thread,
263 // higher on the stack than our highest Run call. Don't preempt other 357 // higher on the stack than our highest Run call. Don't preempt other
264 // run loops, just mark the object to quit our innermost run loop as soon 358 // run loops, just mark the object to quit our innermost run loop as soon
265 // as the other inner loops we don't manage are done. 359 // as the other inner loops we don't manage are done.
266 quit_pending_ = true; 360 quit_pending_ = true;
267 } 361 }
268 } 362 }
269 363
270 // Called from the run loop. 364 // Called by MessagePumpCFRunLoopBase::EnterExitObserver.
271 // static 365 void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) {
272 void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopObserverRef observer, 366 if (activity == kCFRunLoopExit &&
273 CFRunLoopActivity activity, 367 nesting_level_ == innermost_quittable_ &&
274 void* info) { 368 quit_pending_) {
275 MessagePumpCFRunLoop* self = static_cast<MessagePumpCFRunLoop*>(info); 369 // Quit was called while loops other than those managed by this object
276 370 // were running further inside a run loop managed by this object. Now
277 switch (activity) { 371 // that all unmanaged inner run loops are gone, stop the loop running
278 case kCFRunLoopEntry: 372 // just inside Run.
279 // If the run loop was entered by a call to Run, this will properly 373 CFRunLoopStop(run_loop_);
280 // balance the decrement done in Run before entering the loop. 374 quit_pending_ = false;
281 ++self->nesting_level_;
282 break;
283 case kCFRunLoopExit:
284 if (--self->nesting_level_ == self->innermost_quittable_ &&
285 self->quit_pending_) {
286 // Quit was called while loops other than those managed by this object
287 // were running further inside a run loop managed by this object. Now
288 // that all unmanaged inner run loops are gone, stop the loop running
289 // just inside Run.
290 CFRunLoopStop(self->run_loop_);
291 self->quit_pending_ = false;
292 }
293 break;
294 default:
295 break;
296 } 375 }
297 } 376 }
298 377
299 MessagePumpNSRunLoop::MessagePumpNSRunLoop() 378 MessagePumpNSRunLoop::MessagePumpNSRunLoop()
300 : keep_running_(true) { 379 : keep_running_(true) {
301 CFRunLoopSourceContext source_context = CFRunLoopSourceContext(); 380 CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
302 source_context.perform = NoOp; 381 source_context.perform = NoOp;
303 quit_source_ = CFRunLoopSourceCreate(NULL, // allocator 382 quit_source_ = CFRunLoopSourceCreate(NULL, // allocator
304 0, // priority 383 0, // priority
305 &source_context); 384 &source_context);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 // static 461 // static
383 MessagePump* MessagePumpMac::Create() { 462 MessagePump* MessagePumpMac::Create() {
384 if ([NSThread isMainThread]) { 463 if ([NSThread isMainThread]) {
385 return new MessagePumpNSApplication; 464 return new MessagePumpNSApplication;
386 } 465 }
387 466
388 return new MessagePumpNSRunLoop; 467 return new MessagePumpNSRunLoop;
389 } 468 }
390 469
391 } // namespace base 470 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698