Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling Timer Coalescing in OSX for a given process

I have a background application which requires to send a keep-alive to another process every 1.5 seconds. Everything works smoothly in OSX 10.7 and 10.8, but under OSX 10.9 many keep-alive notifications are missed, sometime up to 3. Usually everything works fine for the first 3 or 4 minutes then problems start to occur.

After further inspection, it seems that OSX Mavericks "Timer Coalescing" feature would be responsible for making the decision of extending the requested 1.5 seconds up to 4.0 seconds.

Is there any way to indicate in a NSThread not to coalesce? Or at the very least to indicate the maximum coalescing variations allowed?

See code below for reference:

+(void)keepAliveThread
{
    @autoreleasepool {
        void (^keepAlive)() = ^ (){
            // (snipped!) do something...
        };
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        while( [NSThread currentThread].isCancelled == NO )
        {
            @autoreleasepool {
                dispatch_async(mainQueue, keepAlive);
                [NSThread sleepForTimeInterval:1.5];
            }
        }
    }
}
like image 906
ekscrypto Avatar asked Oct 24 '13 22:10

ekscrypto


1 Answers

A user on the Apple Developer forums actually recommended I watch a video from WWDC 2013 entitled "Improving Power Efficiency with App Nap"; in which I found the solution:

static dispatch_source_t _keepAliveTimer;

+(void)enable
{
    _keepAliveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, dispatch_get_main_queue());
    dispatch_source_set_event_handler(_keepAliveTimer, ^{
        // do something
    });
    dispatch_source_set_timer(_keepAliveTimer, dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC), 1.5 * NSEC_PER_SEC, 0.5 * NSEC_PER_SEC);
    dispatch_resume(_keepAliveTimer);
}

This piece of code will fire a timer at 1.5 seconds (give or take 0.5 seconds) regardless of the LSUIElement state and will prevent App Nap from kicking in for that timer only.

like image 101
ekscrypto Avatar answered Oct 22 '22 06:10

ekscrypto