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

Unified Diff: base/message_loop/message_pump_mac.mm

Issue 2889293002: Filter run loop modes in message_pump_mac.mm (Closed)
Patch Set: respond to comments, sort methods Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_loop/message_pump_mac.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/message_loop/message_pump_mac.mm
diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm
index 370e351ec9cd449c9c281da177dedf0db8aac7c0..305234b8170a610682ac271181471c72ee5e89ef 100644
--- a/base/message_loop/message_pump_mac.mm
+++ b/base/message_loop/message_pump_mac.mm
@@ -44,39 +44,8 @@ const CFStringRef kAllModes[] = {
CFSTR("NSUnhighlightMenuRunLoopMode"),
};
-void CFRunLoopAddSourceToAllModes(CFRunLoopRef rl, CFRunLoopSourceRef source) {
- for (const CFStringRef& mode : kAllModes)
- CFRunLoopAddSource(rl, source, mode);
-}
-
-void CFRunLoopRemoveSourceFromAllModes(CFRunLoopRef rl,
- CFRunLoopSourceRef source) {
- for (const CFStringRef& mode : kAllModes)
- CFRunLoopRemoveSource(rl, source, mode);
-}
-
-void CFRunLoopAddTimerToAllModes(CFRunLoopRef rl, CFRunLoopTimerRef timer) {
- for (const CFStringRef& mode : kAllModes)
- CFRunLoopAddTimer(rl, timer, mode);
-}
-
-void CFRunLoopRemoveTimerFromAllModes(CFRunLoopRef rl,
- CFRunLoopTimerRef timer) {
- for (const CFStringRef& mode : kAllModes)
- CFRunLoopRemoveTimer(rl, timer, mode);
-}
-
-void CFRunLoopAddObserverToAllModes(CFRunLoopRef rl,
- CFRunLoopObserverRef observer) {
- for (const CFStringRef& mode : kAllModes)
- CFRunLoopAddObserver(rl, observer, mode);
-}
-
-void CFRunLoopRemoveObserverFromAllModes(CFRunLoopRef rl,
- CFRunLoopObserverRef observer) {
- for (const CFStringRef& mode : kAllModes)
- CFRunLoopRemoveObserver(rl, observer, mode);
-}
+// Mask that determines which modes in |kAllModes| to use.
+enum { kCommonModeMask = 0x1, kAllModesMask = ~0 };
void NoOp(void* info) {
}
@@ -154,50 +123,61 @@ class MessagePumpScopedAutoreleasePool {
DISALLOW_COPY_AND_ASSIGN(MessagePumpScopedAutoreleasePool);
};
-#if !defined(OS_IOS)
-// This function uses private API to modify a test timer's valid state and
-// uses public API to confirm that the private API changed the correct bit.
-// static
-bool MessagePumpCFRunLoopBase::CanInvalidateCFRunLoopTimers() {
- CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
- timer_context.info = nullptr;
- ScopedCFTypeRef<CFRunLoopTimerRef> test_timer(
- CFRunLoopTimerCreate(NULL, // allocator
- kCFTimeIntervalMax, // fire time
- kCFTimeIntervalMax, // interval
- 0, // flags
- 0, // priority
- nullptr, &timer_context));
- // Should be valid from the start.
- if (!CFRunLoopTimerIsValid(test_timer)) {
- return false;
- }
- // Confirm that the private API can mark the timer invalid.
- __ChromeCFRunLoopTimerSetValid(test_timer, false);
- if (CFRunLoopTimerIsValid(test_timer)) {
- return false;
- }
- // Confirm that the private API can mark the timer valid.
- __ChromeCFRunLoopTimerSetValid(test_timer, true);
- return CFRunLoopTimerIsValid(test_timer);
+// Must be called on the run loop thread.
+void MessagePumpCFRunLoopBase::Run(Delegate* delegate) {
+ // nesting_level_ will be incremented in EnterExitRunLoop, so set
+ // run_nesting_level_ accordingly.
+ int last_run_nesting_level = run_nesting_level_;
+ run_nesting_level_ = nesting_level_ + 1;
+
+ Delegate* last_delegate = delegate_;
+ SetDelegate(delegate);
+
+ DoRun(delegate);
+
+ // Restore the previous state of the object.
+ SetDelegate(last_delegate);
+ run_nesting_level_ = last_run_nesting_level;
}
-#endif // !defined(OS_IOS)
-// static
-void MessagePumpCFRunLoopBase::ChromeCFRunLoopTimerSetValid(
- CFRunLoopTimerRef timer,
- bool valid) {
-#if !defined(OS_IOS)
- static bool can_invalidate_timers = CanInvalidateCFRunLoopTimers();
- if (can_invalidate_timers) {
- __ChromeCFRunLoopTimerSetValid(timer, valid);
+// May be called on any thread.
+void MessagePumpCFRunLoopBase::ScheduleWork() {
+ CFRunLoopSourceSignal(work_source_);
+ CFRunLoopWakeUp(run_loop_);
+}
+
+// Must be called on the run loop thread.
+void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
+ const TimeTicks& delayed_work_time) {
+ TimeDelta delta = delayed_work_time - TimeTicks::Now();
+ delayed_work_fire_time_ = CFAbsoluteTimeGetCurrent() + delta.InSecondsF();
+
+ // Flip the timer's validation bit just before setting the new fire time. Do
+ // this now because CFRunLoopTimerSetNextFireDate() likely checks the validity
+ // of a timer before proceeding to set its fire date. Making the timer valid
+ // now won't have any side effects (such as a premature firing of the timer)
+ // because we're only flipping a bit.
+ //
+ // Please see the comment in RunDelayedWorkTimer() for more info on the whys
+ // of invalidation.
+ ChromeCFRunLoopTimerSetValid(delayed_work_timer_, true);
+
+ CFRunLoopTimerSetNextFireDate(delayed_work_timer_, delayed_work_fire_time_);
+ if (timer_slack_ == TIMER_SLACK_MAXIMUM) {
+ CFRunLoopTimerSetTolerance(delayed_work_timer_, delta.InSecondsF() * 0.5);
+ } else {
+ CFRunLoopTimerSetTolerance(delayed_work_timer_, 0);
}
-#endif // !defined(OS_IOS)
+}
+
+void MessagePumpCFRunLoopBase::SetTimerSlack(TimerSlack timer_slack) {
+ timer_slack_ = timer_slack;
}
// Must be called on the run loop thread.
-MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
- : delegate_(NULL),
+MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase(int mode_mask)
+ : mode_mask_(mode_mask),
+ delegate_(NULL),
delayed_work_fire_time_(kCFTimeIntervalMax),
timer_slack_(base::TIMER_SLACK_NONE),
nesting_level_(0),
@@ -220,7 +200,7 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
0, // priority
RunDelayedWorkTimer,
&timer_context);
- CFRunLoopAddTimerToAllModes(run_loop_, delayed_work_timer_);
+ InvokeForEnabledModes(&CFRunLoopAddTimer, delayed_work_timer_);
CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
source_context.info = this;
@@ -228,19 +208,19 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
work_source_ = CFRunLoopSourceCreate(NULL, // allocator
1, // priority
&source_context);
- CFRunLoopAddSourceToAllModes(run_loop_, work_source_);
+ InvokeForEnabledModes(&CFRunLoopAddSource, work_source_);
source_context.perform = RunIdleWorkSource;
idle_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
2, // priority
&source_context);
- CFRunLoopAddSourceToAllModes(run_loop_, idle_work_source_);
+ InvokeForEnabledModes(&CFRunLoopAddSource, idle_work_source_);
source_context.perform = RunNestingDeferredWorkSource;
nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
0, // priority
&source_context);
- CFRunLoopAddSourceToAllModes(run_loop_, nesting_deferred_work_source_);
+ InvokeForEnabledModes(&CFRunLoopAddSource, nesting_deferred_work_source_);
CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
observer_context.info = this;
@@ -250,7 +230,7 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
0, // priority
PreWaitObserver,
&observer_context);
- CFRunLoopAddObserverToAllModes(run_loop_, pre_wait_observer_);
+ InvokeForEnabledModes(&CFRunLoopAddObserver, pre_wait_observer_);
pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopBeforeSources,
@@ -258,7 +238,7 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
0, // priority
PreSourceObserver,
&observer_context);
- CFRunLoopAddObserverToAllModes(run_loop_, pre_source_observer_);
+ InvokeForEnabledModes(&CFRunLoopAddObserver, pre_source_observer_);
enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopEntry |
@@ -267,54 +247,28 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
0, // priority
EnterExitObserver,
&observer_context);
- CFRunLoopAddObserverToAllModes(run_loop_, enter_exit_observer_);
+ InvokeForEnabledModes(&CFRunLoopAddObserver, enter_exit_observer_);
}
// Ideally called on the run loop thread. If other run loops were running
// lower on the run loop thread's stack when this object was created, the
// same number of run loops must be running when this object is destroyed.
MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() {
- CFRunLoopRemoveObserverFromAllModes(run_loop_, enter_exit_observer_);
- CFRelease(enter_exit_observer_);
-
- CFRunLoopRemoveObserverFromAllModes(run_loop_, pre_source_observer_);
- CFRelease(pre_source_observer_);
-
- CFRunLoopRemoveObserverFromAllModes(run_loop_, pre_wait_observer_);
- CFRelease(pre_wait_observer_);
-
- CFRunLoopRemoveSourceFromAllModes(run_loop_, nesting_deferred_work_source_);
- CFRelease(nesting_deferred_work_source_);
-
- CFRunLoopRemoveSourceFromAllModes(run_loop_, idle_work_source_);
- CFRelease(idle_work_source_);
-
- CFRunLoopRemoveSourceFromAllModes(run_loop_, work_source_);
- CFRelease(work_source_);
-
- CFRunLoopRemoveTimerFromAllModes(run_loop_, delayed_work_timer_);
+ for (const CFRunLoopObserverRef& observer :
+ {enter_exit_observer_, pre_source_observer_, pre_wait_observer_}) {
+ InvokeForEnabledModes(&CFRunLoopRemoveObserver, observer);
+ CFRelease(observer);
+ }
+ for (const CFRunLoopSourceRef& source :
+ {nesting_deferred_work_source_, idle_work_source_, work_source_}) {
+ InvokeForEnabledModes(&CFRunLoopRemoveSource, source);
+ CFRelease(source);
+ }
+ InvokeForEnabledModes(&CFRunLoopRemoveTimer, delayed_work_timer_);
CFRelease(delayed_work_timer_);
-
CFRelease(run_loop_);
}
-// Must be called on the run loop thread.
-void MessagePumpCFRunLoopBase::Run(Delegate* delegate) {
- // nesting_level_ will be incremented in EnterExitRunLoop, so set
- // run_nesting_level_ accordingly.
- int last_run_nesting_level = run_nesting_level_;
- run_nesting_level_ = nesting_level_ + 1;
-
- Delegate* last_delegate = delegate_;
- SetDelegate(delegate);
-
- DoRun(delegate);
-
- // Restore the previous state of the object.
- SetDelegate(last_delegate);
- run_nesting_level_ = last_run_nesting_level;
-}
-
void MessagePumpCFRunLoopBase::SetDelegate(Delegate* delegate) {
delegate_ = delegate;
@@ -333,38 +287,61 @@ void MessagePumpCFRunLoopBase::SetDelegate(Delegate* delegate) {
}
}
-// May be called on any thread.
-void MessagePumpCFRunLoopBase::ScheduleWork() {
- CFRunLoopSourceSignal(work_source_);
- CFRunLoopWakeUp(run_loop_);
+// Base version returns a standard NSAutoreleasePool.
+AutoreleasePoolType* MessagePumpCFRunLoopBase::CreateAutoreleasePool() {
+ return [[NSAutoreleasePool alloc] init];
}
-// Must be called on the run loop thread.
-void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
- const TimeTicks& delayed_work_time) {
- TimeDelta delta = delayed_work_time - TimeTicks::Now();
- delayed_work_fire_time_ = CFAbsoluteTimeGetCurrent() + delta.InSecondsF();
-
- // Flip the timer's validation bit just before setting the new fire time. Do
- // this now because CFRunLoopTimerSetNextFireDate() likely checks the validity
- // of a timer before proceeding to set its fire date. Making the timer valid
- // now won't have any side effects (such as a premature firing of the timer)
- // because we're only flipping a bit.
- //
- // Please see the comment in RunDelayedWorkTimer() for more info on the whys
- // of invalidation.
- ChromeCFRunLoopTimerSetValid(delayed_work_timer_, true);
+template <typename Argument>
+void MessagePumpCFRunLoopBase::InvokeForEnabledModes(void method(CFRunLoopRef,
+ Argument,
+ CFStringRef),
+ Argument argument) {
+ for (size_t i = 0; i < arraysize(kAllModes); ++i) {
+ if (mode_mask_ & (0x1 << i))
+ method(run_loop_, argument, kAllModes[i]);
+ }
+}
- CFRunLoopTimerSetNextFireDate(delayed_work_timer_, delayed_work_fire_time_);
- if (timer_slack_ == TIMER_SLACK_MAXIMUM) {
- CFRunLoopTimerSetTolerance(delayed_work_timer_, delta.InSecondsF() * 0.5);
- } else {
- CFRunLoopTimerSetTolerance(delayed_work_timer_, 0);
+#if !defined(OS_IOS)
+// This function uses private API to modify a test timer's valid state and
+// uses public API to confirm that the private API changed the correct bit.
+// static
+bool MessagePumpCFRunLoopBase::CanInvalidateCFRunLoopTimers() {
+ CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
+ timer_context.info = nullptr;
+ ScopedCFTypeRef<CFRunLoopTimerRef> test_timer(
+ CFRunLoopTimerCreate(NULL, // allocator
+ kCFTimeIntervalMax, // fire time
+ kCFTimeIntervalMax, // interval
+ 0, // flags
+ 0, // priority
+ nullptr, &timer_context));
+ // Should be valid from the start.
+ if (!CFRunLoopTimerIsValid(test_timer)) {
+ return false;
+ }
+ // Confirm that the private API can mark the timer invalid.
+ __ChromeCFRunLoopTimerSetValid(test_timer, false);
+ if (CFRunLoopTimerIsValid(test_timer)) {
+ return false;
}
+ // Confirm that the private API can mark the timer valid.
+ __ChromeCFRunLoopTimerSetValid(test_timer, true);
+ return CFRunLoopTimerIsValid(test_timer);
}
+#endif // !defined(OS_IOS)
-void MessagePumpCFRunLoopBase::SetTimerSlack(TimerSlack timer_slack) {
- timer_slack_ = timer_slack;
+// static
+void MessagePumpCFRunLoopBase::ChromeCFRunLoopTimerSetValid(
+ CFRunLoopTimerRef timer,
+ bool valid) {
+#if !defined(OS_IOS)
+ static bool can_invalidate_timers = CanInvalidateCFRunLoopTimers();
+ if (can_invalidate_timers) {
+ __ChromeCFRunLoopTimerSetValid(timer, valid);
+ }
+#endif // !defined(OS_IOS)
}
// Called from the run loop.
@@ -639,14 +616,8 @@ void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
void MessagePumpCFRunLoopBase::EnterExitRunLoop(CFRunLoopActivity activity) {
}
-// Base version returns a standard NSAutoreleasePool.
-AutoreleasePoolType* MessagePumpCFRunLoopBase::CreateAutoreleasePool() {
- return [[NSAutoreleasePool alloc] init];
-}
-
MessagePumpCFRunLoop::MessagePumpCFRunLoop()
- : quit_pending_(false) {
-}
+ : MessagePumpCFRunLoopBase(kCommonModeMask), quit_pending_(false) {}
MessagePumpCFRunLoop::~MessagePumpCFRunLoop() {}
@@ -697,17 +668,17 @@ void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) {
}
MessagePumpNSRunLoop::MessagePumpNSRunLoop()
- : keep_running_(true) {
+ : MessagePumpCFRunLoopBase(kCommonModeMask), keep_running_(true) {
CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
source_context.perform = NoOp;
quit_source_ = CFRunLoopSourceCreate(NULL, // allocator
0, // priority
&source_context);
- CFRunLoopAddSourceToAllModes(run_loop(), quit_source_);
+ InvokeForEnabledModes(&CFRunLoopAddSource, quit_source_);
}
MessagePumpNSRunLoop::~MessagePumpNSRunLoop() {
- CFRunLoopRemoveSourceFromAllModes(run_loop(), quit_source_);
+ InvokeForEnabledModes(&CFRunLoopRemoveSource, quit_source_);
CFRelease(quit_source_);
}
@@ -729,8 +700,7 @@ void MessagePumpNSRunLoop::Quit() {
#if defined(OS_IOS)
MessagePumpUIApplication::MessagePumpUIApplication()
- : run_loop_(NULL) {
-}
+ : MessagePumpCFRunLoopBase(kCommonModeMask), run_loop_(NULL) {}
MessagePumpUIApplication::~MessagePumpUIApplication() {}
@@ -752,9 +722,9 @@ void MessagePumpUIApplication::Attach(Delegate* delegate) {
#else
MessagePumpNSApplication::MessagePumpNSApplication()
- : keep_running_(true),
- running_own_loop_(false) {
-}
+ : MessagePumpCFRunLoopBase(kAllModesMask),
+ keep_running_(true),
+ running_own_loop_(false) {}
MessagePumpNSApplication::~MessagePumpNSApplication() {}
« 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