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

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

Issue 333473002: Add a CFRunLoop mode for message loop tasks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add multimode helpers Created 6 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
« 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 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #import <Foundation/Foundation.h> 8 #import <Foundation/Foundation.h>
9 9
10 #include <limits> 10 #include <limits>
11 #include <stack> 11 #include <stack>
12 12
13 #include "base/format_macros.h" 13 #include "base/format_macros.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/mac/scoped_cftyperef.h" 15 #include "base/mac/scoped_cftyperef.h"
16 #include "base/message_loop/timer_slack.h" 16 #include "base/message_loop/timer_slack.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/run_loop.h" 18 #include "base/run_loop.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/time/time.h" 20 #include "base/time/time.h"
21 21
22 #if !defined(OS_IOS) 22 #if !defined(OS_IOS)
23 #import <AppKit/AppKit.h> 23 #import <AppKit/AppKit.h>
24 #endif // !defined(OS_IOS) 24 #endif // !defined(OS_IOS)
25 25
26 namespace base {
27
26 namespace { 28 namespace {
27 29
30 void CFRunLoopAddSourceToAllModes(CFRunLoopRef rl, CFRunLoopSourceRef source) {
31 CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
32 CFRunLoopAddSource(rl, source, kMessageLoopExclusiveRunLoopMode);
33 }
34
35 void CFRunLoopRemoveSourceFromAllModes(CFRunLoopRef rl,
36 CFRunLoopSourceRef source) {
37 CFRunLoopRemoveSource(rl, source, kCFRunLoopCommonModes);
38 CFRunLoopRemoveSource(rl, source, kMessageLoopExclusiveRunLoopMode);
39 }
40
41 void CFRunLoopAddTimerToAllModes(CFRunLoopRef rl, CFRunLoopTimerRef timer) {
42 CFRunLoopAddTimer(rl, timer, kCFRunLoopCommonModes);
43 CFRunLoopAddTimer(rl, timer, kMessageLoopExclusiveRunLoopMode);
44 }
45
46 void CFRunLoopRemoveTimerFromAllModes(CFRunLoopRef rl,
47 CFRunLoopTimerRef timer) {
48 CFRunLoopRemoveTimer(rl, timer, kCFRunLoopCommonModes);
49 CFRunLoopRemoveTimer(rl, timer, kMessageLoopExclusiveRunLoopMode);
50 }
51
52 void CFRunLoopAddObserverToAllModes(CFRunLoopRef rl,
53 CFRunLoopObserverRef observer) {
54 CFRunLoopAddObserver(rl, observer, kCFRunLoopCommonModes);
55 CFRunLoopAddObserver(rl, observer, kMessageLoopExclusiveRunLoopMode);
56 }
57
58 void CFRunLoopRemoveObserverFromAllModes(CFRunLoopRef rl,
59 CFRunLoopObserverRef observer) {
60 CFRunLoopRemoveObserver(rl, observer, kCFRunLoopCommonModes);
61 CFRunLoopRemoveObserver(rl, observer, kMessageLoopExclusiveRunLoopMode);
62 }
63
28 void NoOp(void* info) { 64 void NoOp(void* info) {
29 } 65 }
30 66
31 const CFTimeInterval kCFTimeIntervalMax = 67 const CFTimeInterval kCFTimeIntervalMax =
32 std::numeric_limits<CFTimeInterval>::max(); 68 std::numeric_limits<CFTimeInterval>::max();
33 69
34 #if !defined(OS_IOS) 70 #if !defined(OS_IOS)
35 // Set to true if MessagePumpMac::Create() is called before NSApp is 71 // Set to true if MessagePumpMac::Create() is called before NSApp is
36 // initialized. Only accessed from the main thread. 72 // initialized. Only accessed from the main thread.
37 bool g_not_using_cr_app = false; 73 bool g_not_using_cr_app = false;
(...skipping 21 matching lines...) Expand all
59 95
60 dlclose(library_handle); 96 dlclose(library_handle);
61 }); 97 });
62 98
63 if (settimertolerance_function_ptr) 99 if (settimertolerance_function_ptr)
64 settimertolerance_function_ptr(timer, tolerance); 100 settimertolerance_function_ptr(timer, tolerance);
65 } 101 }
66 102
67 } // namespace 103 } // namespace
68 104
69 namespace base { 105 // static
106 const CFStringRef kMessageLoopExclusiveRunLoopMode =
107 CFSTR("kMessageLoopExclusiveRunLoopMode");
70 108
71 // A scoper for autorelease pools created from message pump run loops. 109 // A scoper for autorelease pools created from message pump run loops.
72 // Avoids dirtying up the ScopedNSAutoreleasePool interface for the rare 110 // Avoids dirtying up the ScopedNSAutoreleasePool interface for the rare
73 // case where an autorelease pool needs to be passed in. 111 // case where an autorelease pool needs to be passed in.
74 class MessagePumpScopedAutoreleasePool { 112 class MessagePumpScopedAutoreleasePool {
75 public: 113 public:
76 explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) : 114 explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) :
77 pool_(pump->CreateAutoreleasePool()) { 115 pool_(pump->CreateAutoreleasePool()) {
78 } 116 }
79 ~MessagePumpScopedAutoreleasePool() { 117 ~MessagePumpScopedAutoreleasePool() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 155
118 CFRunLoopTimerContext timer_context = { .info = this }; 156 CFRunLoopTimerContext timer_context = { .info = this };
119 timer_.reset(CFRunLoopTimerCreate( 157 timer_.reset(CFRunLoopTimerCreate(
120 NULL, // allocator 158 NULL, // allocator
121 (Time::Now() + sampling_interval_).ToCFAbsoluteTime(), 159 (Time::Now() + sampling_interval_).ToCFAbsoluteTime(),
122 sampling_interval_.InSecondsF(), 160 sampling_interval_.InSecondsF(),
123 0, // flags 161 0, // flags
124 0, // order 162 0, // order
125 &MessagePumpInstrumentation::TimerFired, 163 &MessagePumpInstrumentation::TimerFired,
126 &timer_context)); 164 &timer_context));
127 CFRunLoopAddTimer(CFRunLoopGetCurrent(), 165 CFRunLoopAddTimerToAllModes(CFRunLoopGetCurrent(), timer_);
128 timer_,
129 kCFRunLoopCommonModes);
130 } 166 }
131 167
132 // Used to track kCFRunLoopEntry. 168 // Used to track kCFRunLoopEntry.
133 void LoopEntered() { 169 void LoopEntered() {
134 loop_run_times_.push(TimeTicks::Now()); 170 loop_run_times_.push(TimeTicks::Now());
135 } 171 }
136 172
137 // Used to track kCFRunLoopExit. 173 // Used to track kCFRunLoopExit.
138 void LoopExited() { 174 void LoopExited() {
139 TimeDelta duration = TimeTicks::Now() - loop_run_times_.top(); 175 TimeDelta duration = TimeTicks::Now() - loop_run_times_.top();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 // as needed when ScheduleDelayedWork is called. 361 // as needed when ScheduleDelayedWork is called.
326 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext(); 362 CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
327 timer_context.info = this; 363 timer_context.info = this;
328 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator 364 delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator
329 kCFTimeIntervalMax, // fire time 365 kCFTimeIntervalMax, // fire time
330 kCFTimeIntervalMax, // interval 366 kCFTimeIntervalMax, // interval
331 0, // flags 367 0, // flags
332 0, // priority 368 0, // priority
333 RunDelayedWorkTimer, 369 RunDelayedWorkTimer,
334 &timer_context); 370 &timer_context);
335 CFRunLoopAddTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes); 371 CFRunLoopAddTimerToAllModes(run_loop_, delayed_work_timer_);
336 372
337 CFRunLoopSourceContext source_context = CFRunLoopSourceContext(); 373 CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
338 source_context.info = this; 374 source_context.info = this;
339 source_context.perform = RunWorkSource; 375 source_context.perform = RunWorkSource;
340 work_source_ = CFRunLoopSourceCreate(NULL, // allocator 376 work_source_ = CFRunLoopSourceCreate(NULL, // allocator
341 1, // priority 377 1, // priority
342 &source_context); 378 &source_context);
343 CFRunLoopAddSource(run_loop_, work_source_, kCFRunLoopCommonModes); 379 CFRunLoopAddSourceToAllModes(run_loop_, work_source_);
344 380
345 source_context.perform = RunIdleWorkSource; 381 source_context.perform = RunIdleWorkSource;
346 idle_work_source_ = CFRunLoopSourceCreate(NULL, // allocator 382 idle_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
347 2, // priority 383 2, // priority
348 &source_context); 384 &source_context);
349 CFRunLoopAddSource(run_loop_, idle_work_source_, kCFRunLoopCommonModes); 385 CFRunLoopAddSourceToAllModes(run_loop_, idle_work_source_);
350 386
351 source_context.perform = RunNestingDeferredWorkSource; 387 source_context.perform = RunNestingDeferredWorkSource;
352 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator 388 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
353 0, // priority 389 0, // priority
354 &source_context); 390 &source_context);
355 CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_, 391 CFRunLoopAddSourceToAllModes(run_loop_, nesting_deferred_work_source_);
356 kCFRunLoopCommonModes);
357 392
358 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext(); 393 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
359 observer_context.info = this; 394 observer_context.info = this;
360 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator 395 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator
361 kCFRunLoopBeforeWaiting | 396 kCFRunLoopBeforeWaiting |
362 kCFRunLoopAfterWaiting, 397 kCFRunLoopAfterWaiting,
363 true, // repeat 398 true, // repeat
364 0, // priority 399 0, // priority
365 StartOrEndWaitObserver, 400 StartOrEndWaitObserver,
366 &observer_context); 401 &observer_context);
367 CFRunLoopAddObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes); 402 CFRunLoopAddObserverToAllModes(run_loop_, pre_wait_observer_);
368 403
369 pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator 404 pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator
370 kCFRunLoopBeforeSources, 405 kCFRunLoopBeforeSources,
371 true, // repeat 406 true, // repeat
372 0, // priority 407 0, // priority
373 PreSourceObserver, 408 PreSourceObserver,
374 &observer_context); 409 &observer_context);
375 CFRunLoopAddObserver(run_loop_, pre_source_observer_, kCFRunLoopCommonModes); 410 CFRunLoopAddObserverToAllModes(run_loop_, pre_source_observer_);
376 411
377 enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator 412 enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator
378 kCFRunLoopEntry | 413 kCFRunLoopEntry |
379 kCFRunLoopExit, 414 kCFRunLoopExit,
380 true, // repeat 415 true, // repeat
381 0, // priority 416 0, // priority
382 EnterExitObserver, 417 EnterExitObserver,
383 &observer_context); 418 &observer_context);
384 CFRunLoopAddObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes); 419 CFRunLoopAddObserverToAllModes(run_loop_, enter_exit_observer_);
385 } 420 }
386 421
387 // Ideally called on the run loop thread. If other run loops were running 422 // Ideally called on the run loop thread. If other run loops were running
388 // lower on the run loop thread's stack when this object was created, the 423 // lower on the run loop thread's stack when this object was created, the
389 // same number of run loops must be running when this object is destroyed. 424 // same number of run loops must be running when this object is destroyed.
390 MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() { 425 MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() {
391 CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_, 426 CFRunLoopRemoveObserverFromAllModes(run_loop_, enter_exit_observer_);
392 kCFRunLoopCommonModes);
393 CFRelease(enter_exit_observer_); 427 CFRelease(enter_exit_observer_);
394 428
395 CFRunLoopRemoveObserver(run_loop_, pre_source_observer_, 429 CFRunLoopRemoveObserverFromAllModes(run_loop_, pre_source_observer_);
396 kCFRunLoopCommonModes);
397 CFRelease(pre_source_observer_); 430 CFRelease(pre_source_observer_);
398 431
399 CFRunLoopRemoveObserver(run_loop_, pre_wait_observer_, 432 CFRunLoopRemoveObserverFromAllModes(run_loop_, pre_wait_observer_);
400 kCFRunLoopCommonModes);
401 CFRelease(pre_wait_observer_); 433 CFRelease(pre_wait_observer_);
402 434
403 CFRunLoopRemoveSource(run_loop_, nesting_deferred_work_source_, 435 CFRunLoopRemoveSourceFromAllModes(run_loop_, nesting_deferred_work_source_);
404 kCFRunLoopCommonModes);
405 CFRelease(nesting_deferred_work_source_); 436 CFRelease(nesting_deferred_work_source_);
406 437
407 CFRunLoopRemoveSource(run_loop_, idle_work_source_, kCFRunLoopCommonModes); 438 CFRunLoopRemoveSourceFromAllModes(run_loop_, idle_work_source_);
408 CFRelease(idle_work_source_); 439 CFRelease(idle_work_source_);
409 440
410 CFRunLoopRemoveSource(run_loop_, work_source_, kCFRunLoopCommonModes); 441 CFRunLoopRemoveSourceFromAllModes(run_loop_, work_source_);
411 CFRelease(work_source_); 442 CFRelease(work_source_);
412 443
413 CFRunLoopRemoveTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes); 444 CFRunLoopRemoveTimerFromAllModes(run_loop_, delayed_work_timer_);
414 CFRelease(delayed_work_timer_); 445 CFRelease(delayed_work_timer_);
415 446
416 CFRelease(run_loop_); 447 CFRelease(run_loop_);
417 } 448 }
418 449
419 // Must be called on the run loop thread. 450 // Must be called on the run loop thread.
420 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) { 451 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) {
421 // nesting_level_ will be incremented in EnterExitRunLoop, so set 452 // nesting_level_ will be incremented in EnterExitRunLoop, so set
422 // run_nesting_level_ accordingly. 453 // run_nesting_level_ accordingly.
423 int last_run_nesting_level = run_nesting_level_; 454 int last_run_nesting_level = run_nesting_level_;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 } 823 }
793 } 824 }
794 825
795 MessagePumpNSRunLoop::MessagePumpNSRunLoop() 826 MessagePumpNSRunLoop::MessagePumpNSRunLoop()
796 : keep_running_(true) { 827 : keep_running_(true) {
797 CFRunLoopSourceContext source_context = CFRunLoopSourceContext(); 828 CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
798 source_context.perform = NoOp; 829 source_context.perform = NoOp;
799 quit_source_ = CFRunLoopSourceCreate(NULL, // allocator 830 quit_source_ = CFRunLoopSourceCreate(NULL, // allocator
800 0, // priority 831 0, // priority
801 &source_context); 832 &source_context);
802 CFRunLoopAddSource(run_loop(), quit_source_, kCFRunLoopCommonModes); 833 CFRunLoopAddSourceToAllModes(run_loop(), quit_source_);
803 } 834 }
804 835
805 MessagePumpNSRunLoop::~MessagePumpNSRunLoop() { 836 MessagePumpNSRunLoop::~MessagePumpNSRunLoop() {
806 CFRunLoopRemoveSource(run_loop(), quit_source_, kCFRunLoopCommonModes); 837 CFRunLoopRemoveSourceFromAllModes(run_loop(), quit_source_);
807 CFRelease(quit_source_); 838 CFRelease(quit_source_);
808 } 839 }
809 840
810 void MessagePumpNSRunLoop::DoRun(Delegate* delegate) { 841 void MessagePumpNSRunLoop::DoRun(Delegate* delegate) {
811 while (keep_running_) { 842 while (keep_running_) {
812 // NSRunLoop manages autorelease pools itself. 843 // NSRunLoop manages autorelease pools itself.
813 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 844 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
814 beforeDate:[NSDate distantFuture]]; 845 beforeDate:[NSDate distantFuture]];
815 } 846 }
816 847
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 [NSApplication sharedApplication]; 1024 [NSApplication sharedApplication];
994 g_not_using_cr_app = true; 1025 g_not_using_cr_app = true;
995 return new MessagePumpNSApplication; 1026 return new MessagePumpNSApplication;
996 #endif 1027 #endif
997 } 1028 }
998 1029
999 return new MessagePumpNSRunLoop; 1030 return new MessagePumpNSRunLoop;
1000 } 1031 }
1001 1032
1002 } // namespace base 1033 } // 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