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

Side by Side Diff: base/message_loop/message_pump_mac.mm

Issue 20792003: DO NOT SUBMIT. Hacky trace event data for MessagePumpMac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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_loop/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) 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 #import "base/message_loop/message_pump_mac.h" 5 #import "base/message_loop/message_pump_mac.h"
6 6
7 #import <Foundation/Foundation.h> 7 #import <Foundation/Foundation.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
11 #include "base/debug/trace_event.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/run_loop.h" 13 #include "base/run_loop.h"
13 #include "base/time/time.h" 14 #include "base/time/time.h"
14 15
15 #if !defined(OS_IOS) 16 #if !defined(OS_IOS)
16 #import <AppKit/AppKit.h> 17 #import <AppKit/AppKit.h>
17 #endif // !defined(OS_IOS) 18 #endif // !defined(OS_IOS)
18 19
19 namespace { 20 namespace {
20 21
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 source_context.perform = RunNestingDeferredWorkSource; 95 source_context.perform = RunNestingDeferredWorkSource;
95 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator 96 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
96 0, // priority 97 0, // priority
97 &source_context); 98 &source_context);
98 CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_, 99 CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_,
99 kCFRunLoopCommonModes); 100 kCFRunLoopCommonModes);
100 101
101 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext(); 102 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
102 observer_context.info = this; 103 observer_context.info = this;
103 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator 104 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator
104 kCFRunLoopBeforeWaiting, 105 kCFRunLoopBeforeWaiting |
106 kCFRunLoopAfterWaiting,
105 true, // repeat 107 true, // repeat
106 0, // priority 108 0, // priority
107 PreWaitObserver, 109 PreWaitObserver,
108 &observer_context); 110 &observer_context);
109 CFRunLoopAddObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes); 111 CFRunLoopAddObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes);
110 112
111 pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator 113 pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator
112 kCFRunLoopBeforeSources, 114 kCFRunLoopBeforeSources,
113 true, // repeat 115 true, // repeat
114 0, // priority 116 0, // priority
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 // CFRunLoopTimers fire outside of the priority scheme for CFRunLoopSources. 221 // CFRunLoopTimers fire outside of the priority scheme for CFRunLoopSources.
220 // In order to establish the proper priority in which work and delayed work 222 // In order to establish the proper priority in which work and delayed work
221 // are processed one for one, the timer used to schedule delayed work must 223 // are processed one for one, the timer used to schedule delayed work must
222 // signal a CFRunLoopSource used to dispatch both work and delayed work. 224 // signal a CFRunLoopSource used to dispatch both work and delayed work.
223 CFRunLoopSourceSignal(self->work_source_); 225 CFRunLoopSourceSignal(self->work_source_);
224 } 226 }
225 227
226 // Called from the run loop. 228 // Called from the run loop.
227 // static 229 // static
228 void MessagePumpCFRunLoopBase::RunWorkSource(void* info) { 230 void MessagePumpCFRunLoopBase::RunWorkSource(void* info) {
231 TRACE_EVENT0("CFRunLoop", "RunWorkSource");
229 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 232 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
230 self->RunWork(); 233 self->RunWork();
231 } 234 }
232 235
233 // Called by MessagePumpCFRunLoopBase::RunWorkSource. 236 // Called by MessagePumpCFRunLoopBase::RunWorkSource.
234 bool MessagePumpCFRunLoopBase::RunWork() { 237 bool MessagePumpCFRunLoopBase::RunWork() {
235 if (!delegate_) { 238 if (!delegate_) {
236 // This point can be reached with a NULL delegate_ if Run is not on the 239 // This point can be reached with a NULL delegate_ if Run is not on the
237 // stack but foreign code is spinning the CFRunLoop. Arrange to come back 240 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
238 // here when a delegate is available. 241 // here when a delegate is available.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 if (resignal_work_source) { 281 if (resignal_work_source) {
279 CFRunLoopSourceSignal(work_source_); 282 CFRunLoopSourceSignal(work_source_);
280 } 283 }
281 284
282 return resignal_work_source; 285 return resignal_work_source;
283 } 286 }
284 287
285 // Called from the run loop. 288 // Called from the run loop.
286 // static 289 // static
287 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) { 290 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) {
291 TRACE_EVENT0("CFRunLoop", "RunWorkIdleSource");
288 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 292 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
289 self->RunIdleWork(); 293 self->RunIdleWork();
290 } 294 }
291 295
292 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource. 296 // Called by MessagePumpCFRunLoopBase::RunIdleWorkSource.
293 bool MessagePumpCFRunLoopBase::RunIdleWork() { 297 bool MessagePumpCFRunLoopBase::RunIdleWork() {
294 if (!delegate_) { 298 if (!delegate_) {
295 // This point can be reached with a NULL delegate_ if Run is not on the 299 // This point can be reached with a NULL delegate_ if Run is not on the
296 // stack but foreign code is spinning the CFRunLoop. Arrange to come back 300 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
297 // here when a delegate is available. 301 // here when a delegate is available.
(...skipping 14 matching lines...) Expand all
312 if (did_work) { 316 if (did_work) {
313 CFRunLoopSourceSignal(idle_work_source_); 317 CFRunLoopSourceSignal(idle_work_source_);
314 } 318 }
315 319
316 return did_work; 320 return did_work;
317 } 321 }
318 322
319 // Called from the run loop. 323 // Called from the run loop.
320 // static 324 // static
321 void MessagePumpCFRunLoopBase::RunNestingDeferredWorkSource(void* info) { 325 void MessagePumpCFRunLoopBase::RunNestingDeferredWorkSource(void* info) {
326 TRACE_EVENT0("CFRunLoop", "RunNestingDeferredWorkSource");
322 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 327 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
323 self->RunNestingDeferredWork(); 328 self->RunNestingDeferredWork();
324 } 329 }
325 330
326 // Called by MessagePumpCFRunLoopBase::RunNestingDeferredWorkSource. 331 // Called by MessagePumpCFRunLoopBase::RunNestingDeferredWorkSource.
327 bool MessagePumpCFRunLoopBase::RunNestingDeferredWork() { 332 bool MessagePumpCFRunLoopBase::RunNestingDeferredWork() {
328 if (!delegate_) { 333 if (!delegate_) {
329 // This point can be reached with a NULL delegate_ if Run is not on the 334 // This point can be reached with a NULL delegate_ if Run is not on the
330 // stack but foreign code is spinning the CFRunLoop. There's no sense in 335 // stack but foreign code is spinning the CFRunLoop. There's no sense in
331 // attempting to do any work or signalling the work sources because 336 // attempting to do any work or signalling the work sources because
(...skipping 29 matching lines...) Expand all
361 } 366 }
362 } 367 }
363 368
364 // Called from the run loop. 369 // Called from the run loop.
365 // static 370 // static
366 void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer, 371 void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
367 CFRunLoopActivity activity, 372 CFRunLoopActivity activity,
368 void* info) { 373 void* info) {
369 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 374 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
370 375
376 static uint32 last_id = 0;
377 if (activity == kCFRunLoopBeforeWaiting)
378 self->nesting_stack_.push(++last_id);
379 uint64_t trace_id = ((uintptr_t)observer << sizeof(uint32)) | self->nesting_st ack_.top();
380 if (activity == kCFRunLoopAfterWaiting) {
381 TRACE_EVENT_ASYNC_END0("CFRunLoop", "Waiting", trace_id);
382 self->nesting_stack_.pop();
383 return;
384 } else {
385 TRACE_EVENT_ASYNC_BEGIN0("CFRunLoop", "Waiting", trace_id);
386 }
387
371 // Attempt to do some idle work before going to sleep. 388 // Attempt to do some idle work before going to sleep.
372 self->RunIdleWork(); 389 self->RunIdleWork();
373 390
374 // The run loop is about to go to sleep. If any of the work done since it 391 // The run loop is about to go to sleep. If any of the work done since it
375 // started or woke up resulted in a nested run loop running, 392 // started or woke up resulted in a nested run loop running,
376 // nesting-deferred work may have accumulated. Schedule it for processing 393 // nesting-deferred work may have accumulated. Schedule it for processing
377 // if appropriate. 394 // if appropriate.
378 self->MaybeScheduleNestingDeferredWork(); 395 self->MaybeScheduleNestingDeferredWork();
379 } 396 }
380 397
(...skipping 11 matching lines...) Expand all
392 // appropriate. 409 // appropriate.
393 self->MaybeScheduleNestingDeferredWork(); 410 self->MaybeScheduleNestingDeferredWork();
394 } 411 }
395 412
396 // Called from the run loop. 413 // Called from the run loop.
397 // static 414 // static
398 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer, 415 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
399 CFRunLoopActivity activity, 416 CFRunLoopActivity activity,
400 void* info) { 417 void* info) {
401 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 418 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
419 static uint32 last_id = 0;
420
421 if (activity == kCFRunLoopEntry)
422 self->nesting_stack_.push(++last_id);
423
424 uint64_t trace_id = ((uintptr_t)observer << sizeof(uint32)) | self->nesting_st ack_.top();
402 425
403 switch (activity) { 426 switch (activity) {
404 case kCFRunLoopEntry: 427 case kCFRunLoopEntry:
428 TRACE_EVENT_ASYNC_BEGIN0("CFRunLoop", "LoopCycle", trace_id);
405 ++self->nesting_level_; 429 ++self->nesting_level_;
406 if (self->nesting_level_ > self->deepest_nesting_level_) { 430 if (self->nesting_level_ > self->deepest_nesting_level_) {
407 self->deepest_nesting_level_ = self->nesting_level_; 431 self->deepest_nesting_level_ = self->nesting_level_;
408 } 432 }
409 break; 433 break;
410 434
411 case kCFRunLoopExit: 435 case kCFRunLoopExit:
412 // Not all run loops go to sleep. If a run loop is stopped before it 436 // Not all run loops go to sleep. If a run loop is stopped before it
413 // goes to sleep due to a CFRunLoopStop call, or if the timeout passed 437 // goes to sleep due to a CFRunLoopStop call, or if the timeout passed
414 // to CFRunLoopRunInMode expires, the run loop may proceed directly from 438 // to CFRunLoopRunInMode expires, the run loop may proceed directly from
415 // handling sources to exiting without any sleep. This most commonly 439 // handling sources to exiting without any sleep. This most commonly
416 // occurs when CFRunLoopRunInMode is passed a timeout of 0, causing it 440 // occurs when CFRunLoopRunInMode is passed a timeout of 0, causing it
417 // to make a single pass through the loop and exit without sleep. Some 441 // to make a single pass through the loop and exit without sleep. Some
418 // native loops use CFRunLoop in this way. Because PreWaitObserver will 442 // native loops use CFRunLoop in this way. Because PreWaitObserver will
419 // not be called in these case, MaybeScheduleNestingDeferredWork needs 443 // not be called in these case, MaybeScheduleNestingDeferredWork needs
420 // to be called here, as the run loop exits. 444 // to be called here, as the run loop exits.
421 // 445 //
422 // MaybeScheduleNestingDeferredWork consults self->nesting_level_ 446 // MaybeScheduleNestingDeferredWork consults self->nesting_level_
423 // to determine whether to schedule nesting-deferred work. It expects 447 // to determine whether to schedule nesting-deferred work. It expects
424 // the nesting level to be set to the depth of the loop that is going 448 // the nesting level to be set to the depth of the loop that is going
425 // to sleep or exiting. It must be called before decrementing the 449 // to sleep or exiting. It must be called before decrementing the
426 // value so that the value still corresponds to the level of the exiting 450 // value so that the value still corresponds to the level of the exiting
427 // loop. 451 // loop.
428 self->MaybeScheduleNestingDeferredWork(); 452 self->MaybeScheduleNestingDeferredWork();
429 --self->nesting_level_; 453 --self->nesting_level_;
454 TRACE_EVENT_ASYNC_END0("CFRunLoop", "LoopCycle", trace_id);
455 self->nesting_stack_.pop();
430 break; 456 break;
431 457
432 default: 458 default:
433 break; 459 break;
434 } 460 }
435 461
436 self->EnterExitRunLoop(activity); 462 self->EnterExitRunLoop(activity);
437 } 463 }
438 464
439 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default 465 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default
(...skipping 14 matching lines...) Expand all
454 480
455 // Called by MessagePumpCFRunLoopBase::DoRun. If other CFRunLoopRun loops were 481 // Called by MessagePumpCFRunLoopBase::DoRun. If other CFRunLoopRun loops were
456 // running lower on the run loop thread's stack when this object was created, 482 // running lower on the run loop thread's stack when this object was created,
457 // the same number of CFRunLoopRun loops must be running for the outermost call 483 // the same number of CFRunLoopRun loops must be running for the outermost call
458 // to Run. Run/DoRun are reentrant after that point. 484 // to Run. Run/DoRun are reentrant after that point.
459 void MessagePumpCFRunLoop::DoRun(Delegate* delegate) { 485 void MessagePumpCFRunLoop::DoRun(Delegate* delegate) {
460 // This is completely identical to calling CFRunLoopRun(), except autorelease 486 // This is completely identical to calling CFRunLoopRun(), except autorelease
461 // pool management is introduced. 487 // pool management is introduced.
462 int result; 488 int result;
463 do { 489 do {
490 TRACE_EVENT0("CFRunLoop", "DoRun");
464 MessagePumpScopedAutoreleasePool autorelease_pool(this); 491 MessagePumpScopedAutoreleasePool autorelease_pool(this);
465 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 492 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode,
466 kCFTimeIntervalMax, 493 kCFTimeIntervalMax,
467 false); 494 false);
468 } while (result != kCFRunLoopRunStopped && result != kCFRunLoopRunFinished); 495 } while (result != kCFRunLoopRunStopped && result != kCFRunLoopRunFinished);
469 } 496 }
470 497
471 // Must be called on the run loop thread. 498 // Must be called on the run loop thread.
472 void MessagePumpCFRunLoop::Quit() { 499 void MessagePumpCFRunLoop::Quit() {
473 // Stop the innermost run loop managed by this MessagePumpCFRunLoop object. 500 // Stop the innermost run loop managed by this MessagePumpCFRunLoop object.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 CFRunLoopAddSource(run_loop(), quit_source_, kCFRunLoopCommonModes); 535 CFRunLoopAddSource(run_loop(), quit_source_, kCFRunLoopCommonModes);
509 } 536 }
510 537
511 MessagePumpNSRunLoop::~MessagePumpNSRunLoop() { 538 MessagePumpNSRunLoop::~MessagePumpNSRunLoop() {
512 CFRunLoopRemoveSource(run_loop(), quit_source_, kCFRunLoopCommonModes); 539 CFRunLoopRemoveSource(run_loop(), quit_source_, kCFRunLoopCommonModes);
513 CFRelease(quit_source_); 540 CFRelease(quit_source_);
514 } 541 }
515 542
516 void MessagePumpNSRunLoop::DoRun(Delegate* delegate) { 543 void MessagePumpNSRunLoop::DoRun(Delegate* delegate) {
517 while (keep_running_) { 544 while (keep_running_) {
545 TRACE_EVENT0("NSRunLoop", "DoRun");
518 // NSRunLoop manages autorelease pools itself. 546 // NSRunLoop manages autorelease pools itself.
519 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 547 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
520 beforeDate:[NSDate distantFuture]]; 548 beforeDate:[NSDate distantFuture]];
521 } 549 }
522 550
523 keep_running_ = true; 551 keep_running_ = true;
524 } 552 }
525 553
526 void MessagePumpNSRunLoop::Quit() { 554 void MessagePumpNSRunLoop::Quit() {
527 keep_running_ = false; 555 keep_running_ = false;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 CHECK(NSApp); 599 CHECK(NSApp);
572 600
573 if (![NSApp isRunning]) { 601 if (![NSApp isRunning]) {
574 running_own_loop_ = false; 602 running_own_loop_ = false;
575 // NSApplication manages autorelease pools itself when run this way. 603 // NSApplication manages autorelease pools itself when run this way.
576 [NSApp run]; 604 [NSApp run];
577 } else { 605 } else {
578 running_own_loop_ = true; 606 running_own_loop_ = true;
579 NSDate* distant_future = [NSDate distantFuture]; 607 NSDate* distant_future = [NSDate distantFuture];
580 while (keep_running_) { 608 while (keep_running_) {
609 TRACE_EVENT0("NSApplication", "DoRun");
581 MessagePumpScopedAutoreleasePool autorelease_pool(this); 610 MessagePumpScopedAutoreleasePool autorelease_pool(this);
582 NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask 611 NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
583 untilDate:distant_future 612 untilDate:distant_future
584 inMode:NSDefaultRunLoopMode 613 inMode:NSDefaultRunLoopMode
585 dequeue:YES]; 614 dequeue:YES];
586 if (event) { 615 if (event) {
587 [NSApp sendEvent:event]; 616 [NSApp sendEvent:event];
588 } 617 }
589 } 618 }
590 keep_running_ = true; 619 keep_running_ = true;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 [NSApplication sharedApplication]; 724 [NSApplication sharedApplication];
696 g_not_using_cr_app = true; 725 g_not_using_cr_app = true;
697 return new MessagePumpNSApplication; 726 return new MessagePumpNSApplication;
698 #endif 727 #endif
699 } 728 }
700 729
701 return new MessagePumpNSRunLoop; 730 return new MessagePumpNSRunLoop;
702 } 731 }
703 732
704 } // namespace base 733 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_pump_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698