| 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 891cc347448ff70b30f9357ff431d46aad613f59..d3b4151e95cc53e03ef3158994b8696a1b78d043 100644
|
| --- a/base/message_loop/message_pump_mac.mm
|
| +++ b/base/message_loop/message_pump_mac.mm
|
| @@ -6,6 +6,7 @@
|
|
|
| #import <Foundation/Foundation.h>
|
|
|
| +#include <dlfcn.h>
|
| #include <limits>
|
| #include <stack>
|
|
|
| @@ -13,6 +14,7 @@
|
| #include "base/logging.h"
|
| #include "base/mac/scoped_cftyperef.h"
|
| #include "base/metrics/histogram.h"
|
| +#include "base/message_loop/timer_slack.h"
|
| #include "base/run_loop.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/time/time.h"
|
| @@ -35,6 +37,31 @@ const CFTimeInterval kCFTimeIntervalMax =
|
| bool g_not_using_cr_app = false;
|
| #endif
|
|
|
| +// Call through to CFRunLoopTimerSetTolerance(), which is only available on
|
| +// OS X 10.9.
|
| +void SetTimerTolerance(CFRunLoopTimerRef timer, CFTimeInterval tolerance) {
|
| + typedef void (*CFRunLoopTimerSetTolerancePtr)(CFRunLoopTimerRef timer,
|
| + CFTimeInterval tolerance);
|
| +
|
| + static CFRunLoopTimerSetTolerancePtr settimertolerance_function_ptr = NULL;
|
| + static bool function_lookup_error = false;
|
| +
|
| + if (function_lookup_error)
|
| + return;
|
| +
|
| + if (!settimertolerance_function_ptr) {
|
| + settimertolerance_function_ptr =
|
| + reinterpret_cast<CFRunLoopTimerSetTolerancePtr>(
|
| + dlsym(RTLD_DEFAULT, "CFRunLoopTimerSetTolerance"));
|
| + if (!settimertolerance_function_ptr) {
|
| + function_lookup_error = true;
|
| + return;
|
| + }
|
| + }
|
| +
|
| + settimertolerance_function_ptr(timer, tolerance);
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace base {
|
| @@ -438,6 +465,11 @@ void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
|
| TimeDelta delta = delayed_work_time - TimeTicks::Now();
|
| delayed_work_fire_time_ = CFAbsoluteTimeGetCurrent() + delta.InSecondsF();
|
| CFRunLoopTimerSetNextFireDate(delayed_work_timer_, delayed_work_fire_time_);
|
| + if (GetTimerSlack() == TIMER_SLACK_MAXIMUM) {
|
| + SetTimerTolerance(delayed_work_timer_, delta.InSecondsF() * 0.5);
|
| + } else {
|
| + SetTimerTolerance(delayed_work_timer_, 0);
|
| + }
|
| }
|
|
|
| // Called from the run loop.
|
|
|