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

Side by Side Diff: base/message_pump_mac.mm

Issue 300044: Change the strategy used to attempt nesting-deferred work to account equally... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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 : nesting_level_(0), 25 : delegate_(NULL),
26 nesting_level_(0),
26 run_nesting_level_(0), 27 run_nesting_level_(0),
27 delegate_(NULL), 28 deepest_nesting_level_(0),
28 delegateless_work_(false), 29 delegateless_work_(false),
29 delegateless_delayed_work_(false), 30 delegateless_delayed_work_(false),
30 delegateless_idle_work_(false) 31 delegateless_idle_work_(false) {
31 {
32 run_loop_ = CFRunLoopGetCurrent(); 32 run_loop_ = CFRunLoopGetCurrent();
33 CFRetain(run_loop_); 33 CFRetain(run_loop_);
34 34
35 // Set a repeating timer with a preposterous firing time and interval. The 35 // Set a repeating timer with a preposterous firing time and interval. The
36 // timer will effectively never fire as-is. The firing time will be adjusted 36 // timer will effectively never fire as-is. The firing time will be adjusted
37 // as needed when ScheduleDelayedWork is called. 37 // as needed when ScheduleDelayedWork is called.
38 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext(); 38 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
39 timer_context.info = this; 39 timer_context.info = this;
40 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator 40 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator
41 DBL_MAX, // fire time 41 DBL_MAX, // fire time
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 // Must be called on the run loop thread. 127 // Must be called on the run loop thread.
128 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) { 128 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) {
129 // nesting_level_ will be incremented in EnterExitRunLoop, so set 129 // nesting_level_ will be incremented in EnterExitRunLoop, so set
130 // run_nesting_level_ accordingly. 130 // run_nesting_level_ accordingly.
131 int last_run_nesting_level = run_nesting_level_; 131 int last_run_nesting_level = run_nesting_level_;
132 run_nesting_level_ = nesting_level_ + 1; 132 run_nesting_level_ = nesting_level_ + 1;
133 133
134 Delegate* last_delegate = delegate_; 134 Delegate* last_delegate = delegate_;
135 delegate_ = delegate; 135 delegate_ = delegate;
136 136
137 // If any work showed up but could not be dispatched for want of a delegate, 137 if (delegate) {
138 // set it up for dispatch again now that a delegate is available. 138 // If any work showed up but could not be dispatched for want of a
139 if (delegateless_work_) { 139 // delegate, set it up for dispatch again now that a delegate is
140 CFRunLoopSourceSignal(work_source_); 140 // available.
141 delegateless_work_ = false; 141 if (delegateless_work_) {
142 } 142 CFRunLoopSourceSignal(work_source_);
143 if (delegateless_delayed_work_) { 143 delegateless_work_ = false;
144 CFRunLoopSourceSignal(delayed_work_source_); 144 }
145 delegateless_delayed_work_ = false; 145 if (delegateless_delayed_work_) {
146 } 146 CFRunLoopSourceSignal(delayed_work_source_);
147 if (delegateless_idle_work_) { 147 delegateless_delayed_work_ = false;
148 CFRunLoopSourceSignal(idle_work_source_); 148 }
149 delegateless_idle_work_ = false; 149 if (delegateless_idle_work_) {
150 CFRunLoopSourceSignal(idle_work_source_);
151 delegateless_idle_work_ = false;
152 }
150 } 153 }
151 154
152 DoRun(delegate); 155 DoRun(delegate);
153 156
154 // If this was an inner Run invocation, arrange to run nesting-deferred work
155 // when the stack has unwound to an outer invocation.
156 if (nesting_level_)
157 CFRunLoopSourceSignal(nesting_deferred_work_source_);
158
159 // Restore the previous state of the object. 157 // Restore the previous state of the object.
160 delegate_ = last_delegate; 158 delegate_ = last_delegate;
161 run_nesting_level_ = last_run_nesting_level; 159 run_nesting_level_ = last_run_nesting_level;
162 } 160 }
163 161
164 // May be called on any thread. 162 // May be called on any thread.
165 void MessagePumpCFRunLoopBase::ScheduleWork() { 163 void MessagePumpCFRunLoopBase::ScheduleWork() {
166 CFRunLoopSourceSignal(work_source_); 164 CFRunLoopSourceSignal(work_source_);
167 CFRunLoopWakeUp(run_loop_); 165 CFRunLoopWakeUp(run_loop_);
168 } 166 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // Called by MessagePumpCFRunLoopBase::RunWorkSource. 211 // Called by MessagePumpCFRunLoopBase::RunWorkSource.
214 bool MessagePumpCFRunLoopBase::RunWork() { 212 bool MessagePumpCFRunLoopBase::RunWork() {
215 if (!delegate_) { 213 if (!delegate_) {
216 // This point can be reached with a NULL delegate_ if Run is not on the 214 // This point can be reached with a NULL delegate_ if Run is not on the
217 // stack but foreign code is spinning the CFRunLoop. Arrange to come back 215 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
218 // here when a delegate is available. 216 // here when a delegate is available.
219 delegateless_work_ = true; 217 delegateless_work_ = true;
220 return false; 218 return false;
221 } 219 }
222 220
223 // If we're on the main event loop, the NSApp runloop won't clean up the 221 // The NSApplication-based run loop only drains the autorelease pool at each
224 // autorelease pool until there is a UI event, so use a local one for any 222 // UI event (NSEvent). The autorelease pool is not drained for each
225 // autoreleased objects to ensure they go away sooner. 223 // CFRunLoopSource target that's run. Use a local pool for any autoreleased
224 // objects to ensure they're released promptly even in the absence of UI
225 // events.
226 ScopedNSAutoreleasePool autorelease_pool; 226 ScopedNSAutoreleasePool autorelease_pool;
227 227
228 // Call DoWork once, and if something was done, arrange to come back here 228 // Call DoWork once, and if something was done, arrange to come back here
229 // again as long as the loop is still running. 229 // again as long as the loop is still running.
230 bool did_work = delegate_->DoWork(); 230 bool did_work = delegate_->DoWork();
231 if (did_work) { 231 if (did_work) {
232 CFRunLoopSourceSignal(work_source_); 232 CFRunLoopSourceSignal(work_source_);
233 } 233 }
234 234
235 return did_work; 235 return did_work;
236 } 236 }
237 237
238 // Called from the run loop. 238 // Called from the run loop.
239 // static 239 // static
240 void MessagePumpCFRunLoopBase::RunDelayedWorkSource(void* info) { 240 void MessagePumpCFRunLoopBase::RunDelayedWorkSource(void* info) {
241 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 241 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
242 self->RunDelayedWork(); 242 self->RunDelayedWork();
243 } 243 }
244 244
245 // Called by MessagePumpCFRunLoopBase::RunDelayedWorkSource. 245 // Called by MessagePumpCFRunLoopBase::RunDelayedWorkSource.
246 bool MessagePumpCFRunLoopBase::RunDelayedWork() { 246 bool MessagePumpCFRunLoopBase::RunDelayedWork() {
247 if (!delegate_) { 247 if (!delegate_) {
248 // This point can be reached with a NULL delegate_ if Run is not on the 248 // This point can be reached with a NULL delegate_ if Run is not on the
249 // stack but foreign code is spinning the CFRunLoop. Arrange to come back 249 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
250 // here when a delegate is available. 250 // here when a delegate is available.
251 delegateless_delayed_work_ = true; 251 delegateless_delayed_work_ = true;
252 return false; 252 return false;
253 } 253 }
254 254
255 // If we're on the main event loop, the NSApp runloop won't clean up the 255 // The NSApplication-based run loop only drains the autorelease pool at each
256 // autorelease pool until there is a UI event, so use a local one for any 256 // UI event (NSEvent). The autorelease pool is not drained for each
257 // autoreleased objects to ensure they go away sooner. 257 // CFRunLoopSource target that's run. Use a local pool for any autoreleased
258 // objects to ensure they're released promptly even in the absence of UI
259 // events.
258 ScopedNSAutoreleasePool autorelease_pool; 260 ScopedNSAutoreleasePool autorelease_pool;
259 261
260 Time next_time; 262 Time next_time;
261 delegate_->DoDelayedWork(&next_time); 263 delegate_->DoDelayedWork(&next_time);
262 264
263 bool more_work = !next_time.is_null(); 265 bool more_work = !next_time.is_null();
264 if (more_work) { 266 if (more_work) {
265 TimeDelta delay = next_time - Time::Now(); 267 TimeDelta delay = next_time - Time::Now();
266 if (delay > TimeDelta()) { 268 if (delay > TimeDelta()) {
267 // There's more delayed work to be done in the future. 269 // There's more delayed work to be done in the future.
(...skipping 19 matching lines...) Expand all
287 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource. 289 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource.
288 bool MessagePumpCFRunLoopBase::RunIdleWork() { 290 bool MessagePumpCFRunLoopBase::RunIdleWork() {
289 if (!delegate_) { 291 if (!delegate_) {
290 // This point can be reached with a NULL delegate_ if Run is not on the 292 // This point can be reached with a NULL delegate_ if Run is not on the
291 // stack but foreign code is spinning the CFRunLoop. Arrange to come back 293 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
292 // here when a delegate is available. 294 // here when a delegate is available.
293 delegateless_idle_work_ = true; 295 delegateless_idle_work_ = true;
294 return false; 296 return false;
295 } 297 }
296 298
297 // If we're on the main event loop, the NSApp runloop won't clean up the 299 // The NSApplication-based run loop only drains the autorelease pool at each
298 // autorelease pool until there is a UI event, so use a local one for any 300 // UI event (NSEvent). The autorelease pool is not drained for each
299 // autoreleased objects to ensure they go away sooner. 301 // CFRunLoopSource target that's run. Use a local pool for any autoreleased
302 // objects to ensure they're released promptly even in the absence of UI
303 // events.
300 ScopedNSAutoreleasePool autorelease_pool; 304 ScopedNSAutoreleasePool autorelease_pool;
301 305
302 // Call DoIdleWork once, and if something was done, arrange to come back here 306 // Call DoIdleWork once, and if something was done, arrange to come back here
303 // again as long as the loop is still running. 307 // again as long as the loop is still running.
304 bool did_work = delegate_->DoIdleWork(); 308 bool did_work = delegate_->DoIdleWork();
305 if (did_work) { 309 if (did_work) {
306 CFRunLoopSourceSignal(idle_work_source_); 310 CFRunLoopSourceSignal(idle_work_source_);
307 } 311 }
308 312
309 return did_work; 313 return did_work;
(...skipping 30 matching lines...) Expand all
340 } else { 344 } else {
341 // Work was done. Arrange for the loop to try non-nestable delayed and 345 // Work was done. Arrange for the loop to try non-nestable delayed and
342 // idle work on a subsequent pass. 346 // idle work on a subsequent pass.
343 CFRunLoopSourceSignal(delayed_work_source_); 347 CFRunLoopSourceSignal(delayed_work_source_);
344 CFRunLoopSourceSignal(idle_work_source_); 348 CFRunLoopSourceSignal(idle_work_source_);
345 } 349 }
346 350
347 return true; 351 return true;
348 } 352 }
349 353
354 // Called before the run loop goes to sleep or exits.
355 void MessagePumpCFRunLoopBase::MaybeScheduleNestingDeferredWork() {
356 // deepest_nesting_level_ is set as run loops are entered. If the deepest
357 // level encountered is deeper than the current level (about to sleep or
358 // exit), a nested loop (relative to the current level) ran since the last
359 // time nesting-deferred work was scheduled. When that situation is
360 // encountered, schedule nesting-deferred work in case any work was deferred
361 // because nested work was disallowed.
362 if (deepest_nesting_level_ > nesting_level_) {
363 deepest_nesting_level_ = nesting_level_;
364 CFRunLoopSourceSignal(nesting_deferred_work_source_);
365 }
366 }
367
350 // Called from the run loop. 368 // Called from the run loop.
351 // static 369 // static
352 void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer, 370 void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
353 CFRunLoopActivity activity, 371 CFRunLoopActivity activity,
354 void* info) { 372 void* info) {
355 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 373 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
356 374
357 // Attempt to do some idle work before going to sleep. 375 // Attempt to do some idle work before going to sleep.
358 self->RunIdleWork(); 376 self->RunIdleWork();
377
378 // The run loop is about to go to sleep. If any of the work done since it
379 // started or woke up resulted in a nested run loop running,
380 // nesting-deferred work may have accumulated. Schedule it for processing
381 // if appropriate.
382 self->MaybeScheduleNestingDeferredWork();
359 } 383 }
360 384
361 // Called from the run loop. 385 // Called from the run loop.
362 // static 386 // static
363 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer, 387 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
364 CFRunLoopActivity activity, 388 CFRunLoopActivity activity,
365 void* info) { 389 void* info) {
366 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 390 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
367 391
368 switch (activity) { 392 switch (activity) {
369 case kCFRunLoopEntry: 393 case kCFRunLoopEntry:
370 ++self->nesting_level_; 394 ++self->nesting_level_;
395 if (self->nesting_level_ > self->deepest_nesting_level_) {
396 self->deepest_nesting_level_ = self->nesting_level_;
397 }
371 break; 398 break;
372 case kCFRunLoopExit: 399 case kCFRunLoopExit:
373 // After decrementing self->nesting_level_, it will be one less than 400 // Not all run loops go to sleep. If a run loop is stopped before it
374 // self->run_nesting_level_ if the loop that is now exiting was directly 401 // goes to sleep due to a CFRunLoopStop call, or if the timeout passed
375 // started by a DoRun call. 402 // to CFRunLoopRunInMode expires, the run loop may proceed directly from
403 // handling sources to exiting without any sleep. This most commonly
404 // occurs when CFRunLoopRunInMode is passed a timeout of 0, causing it
405 // to make a single pass through the loop and exit without sleep. Some
406 // native loops use CFRunLoop in this way. Because PreWaitObserver will
407 // not be called in these case, MaybeScheduleNestingDeferredWork needs
408 // to be called here, as the run loop exits.
409 //
410 // MaybeScheduleNestingDeferredWork consults self->nesting_level_
411 // to determine whether to schedule nesting-deferred work. It expects
412 // the nesting level to be set to the depth of the loop that is going
413 // to sleep or exiting. It must be called before decrementing the
414 // value so that the value still corresponds to the level of the exiting
415 // loop.
416 self->MaybeScheduleNestingDeferredWork();
376 --self->nesting_level_; 417 --self->nesting_level_;
377
378 if (self->nesting_level_ >= self->run_nesting_level_ &&
379 self->nesting_level_) {
380 // It's possible that some work was not performed because it was
381 // inappropriate to do within a nested loop. When leaving any inner
382 // loop not directly supervised by a DoRun call, such as nested native
383 // loops, signal the nesting-deferred work source to ensure that such
384 // work be afforded an opportunity to be processed if appropriate.
385 // This is not done for loops being run directly by Run/DoRun because
386 // it can be done directly as Run exits.
387 CFRunLoopSourceSignal(self->nesting_deferred_work_source_);
388 }
389 break; 418 break;
390 default: 419 default:
391 break; 420 break;
392 } 421 }
393 422
394 self->EnterExitRunLoop(activity); 423 self->EnterExitRunLoop(activity);
395 } 424 }
396 425
397 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default 426 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default
398 // implementation is a no-op. 427 // implementation is a no-op.
(...skipping 14 matching lines...) Expand all
413 int result; 442 int result;
414 do { 443 do {
415 ScopedNSAutoreleasePool autorelease_pool; 444 ScopedNSAutoreleasePool autorelease_pool;
416 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, DBL_MAX, false); 445 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, DBL_MAX, false);
417 } while (result != kCFRunLoopRunStopped && result != kCFRunLoopRunFinished); 446 } while (result != kCFRunLoopRunStopped && result != kCFRunLoopRunFinished);
418 } 447 }
419 448
420 // Must be called on the run loop thread. 449 // Must be called on the run loop thread.
421 void MessagePumpCFRunLoop::Quit() { 450 void MessagePumpCFRunLoop::Quit() {
422 // Stop the innermost run loop managed by this MessagePumpCFRunLoop object. 451 // Stop the innermost run loop managed by this MessagePumpCFRunLoop object.
423 if (nesting_level_ == run_nesting_level_) { 452 if (nesting_level() == run_nesting_level()) {
424 // This object is running the innermost loop, just stop it. 453 // This object is running the innermost loop, just stop it.
425 CFRunLoopStop(run_loop_); 454 CFRunLoopStop(run_loop());
426 } else { 455 } else {
427 // There's another loop running inside the loop managed by this object. 456 // There's another loop running inside the loop managed by this object.
428 // In other words, someone else called CFRunLoopRun on the same thread, 457 // In other words, someone else called CFRunLoopRunInMode on the same
429 // higher on the stack than our highest Run call. Don't preempt other 458 // thread, deeper on the stack than the deepest Run call. Don't preempt
430 // run loops, just mark the object to quit our innermost run loop as soon 459 // other run loops, just mark this object to quit the innermost Run as
431 // as the other inner loops we don't manage are done. 460 // soon as the other inner loops not managed by Run are done.
432 quit_pending_ = true; 461 quit_pending_ = true;
433 } 462 }
434 } 463 }
435 464
436 // Called by MessagePumpCFRunLoopBase::EnterExitObserver. 465 // Called by MessagePumpCFRunLoopBase::EnterExitObserver.
437 void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) { 466 void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) {
438 if (activity == kCFRunLoopExit && 467 if (activity == kCFRunLoopExit &&
439 nesting_level_ == run_nesting_level_ && 468 nesting_level() == run_nesting_level() &&
440 quit_pending_) { 469 quit_pending_) {
441 // Quit was called while loops other than those managed by this object 470 // Quit was called while loops other than those managed by this object
442 // were running further inside a run loop managed by this object. Now 471 // were running further inside a run loop managed by this object. Now
443 // that all unmanaged inner run loops are gone, stop the loop running 472 // that all unmanaged inner run loops are gone, stop the loop running
444 // just inside Run. 473 // just inside Run.
445 CFRunLoopStop(run_loop_); 474 CFRunLoopStop(run_loop());
446 quit_pending_ = false; 475 quit_pending_ = false;
447 } 476 }
448 } 477 }
449 478
450 MessagePumpNSRunLoop::MessagePumpNSRunLoop() 479 MessagePumpNSRunLoop::MessagePumpNSRunLoop()
451 : keep_running_(true) { 480 : keep_running_(true) {
452 CFRunLoopSourceContext source_context = CFRunLoopSourceContext(); 481 CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
453 source_context.perform = NoOp; 482 source_context.perform = NoOp;
454 quit_source_ = CFRunLoopSourceCreate(NULL, // allocator 483 quit_source_ = CFRunLoopSourceCreate(NULL, // allocator
455 0, // priority 484 0, // priority
456 &source_context); 485 &source_context);
457 CFRunLoopAddSource(run_loop_, quit_source_, kCFRunLoopCommonModes); 486 CFRunLoopAddSource(run_loop(), quit_source_, kCFRunLoopCommonModes);
458 } 487 }
459 488
460 MessagePumpNSRunLoop::~MessagePumpNSRunLoop() { 489 MessagePumpNSRunLoop::~MessagePumpNSRunLoop() {
461 CFRunLoopRemoveSource(run_loop_, quit_source_, kCFRunLoopCommonModes); 490 CFRunLoopRemoveSource(run_loop(), quit_source_, kCFRunLoopCommonModes);
462 CFRelease(quit_source_); 491 CFRelease(quit_source_);
463 } 492 }
464 493
465 void MessagePumpNSRunLoop::DoRun(Delegate* delegate) { 494 void MessagePumpNSRunLoop::DoRun(Delegate* delegate) {
466 while (keep_running_) { 495 while (keep_running_) {
467 // NSRunLoop manages autorelease pools itself. 496 // NSRunLoop manages autorelease pools itself.
468 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 497 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
469 beforeDate:[NSDate distantFuture]]; 498 beforeDate:[NSDate distantFuture]];
470 } 499 }
471 500
472 keep_running_ = true; 501 keep_running_ = true;
473 } 502 }
474 503
475 void MessagePumpNSRunLoop::Quit() { 504 void MessagePumpNSRunLoop::Quit() {
476 keep_running_ = false; 505 keep_running_ = false;
477 CFRunLoopSourceSignal(quit_source_); 506 CFRunLoopSourceSignal(quit_source_);
478 CFRunLoopWakeUp(run_loop_); 507 CFRunLoopWakeUp(run_loop());
479 } 508 }
480 509
481 MessagePumpNSApplication::MessagePumpNSApplication() 510 MessagePumpNSApplication::MessagePumpNSApplication()
482 : keep_running_(true), 511 : keep_running_(true),
483 running_own_loop_(false) { 512 running_own_loop_(false) {
484 } 513 }
485 514
486 void MessagePumpNSApplication::DoRun(Delegate* delegate) { 515 void MessagePumpNSApplication::DoRun(Delegate* delegate) {
487 bool last_running_own_loop_ = running_own_loop_; 516 bool last_running_own_loop_ = running_own_loop_;
488 517
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 // static 562 // static
534 MessagePump* MessagePumpMac::Create() { 563 MessagePump* MessagePumpMac::Create() {
535 if ([NSThread isMainThread]) { 564 if ([NSThread isMainThread]) {
536 return new MessagePumpNSApplication; 565 return new MessagePumpNSApplication;
537 } 566 }
538 567
539 return new MessagePumpNSRunLoop; 568 return new MessagePumpNSRunLoop;
540 } 569 }
541 570
542 } // namespace base 571 } // 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