Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using dispatch_sync as a mutex lock

Here is what I need to do. I hope dispatch_sync would be the best way to do it using GCD

I have a certain piece of critical section code that is placed in the applicationDidBecomeActive callback in Appdelegate..

I am wrapping up that method inside a dispatch_sync call so that it gets called only once no matter how many times applicationDidBecomeActive is called

- (void)applicationDidBecomeActive:(UIApplication *)application{    
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    
    NSLog(@"Thread created");
    //crtical code
    [self runCriticalSection];        
});}

Is this the right way for doing it using dispatch_sync?

like image 995
Mr.Anonymous Avatar asked May 01 '13 20:05

Mr.Anonymous


1 Answers

dispatch_sync() does not return until the block has finished, which means that applicationDidBecomeActive does not return until runCriticalSection has finished execution.

This is probably not what you want, therefore you have to use dispatch_async() (as already stated in the other answer).

But you don't want another runCriticalSection to start if the previous one is still running. This can be achieved with a "counting semaphore" (which are also a feature of GCD):

static dispatch_semaphore_t sema; // The semaphore
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // Initialize with count=1 (this is executed only once):
    sema = dispatch_semaphore_create(1);
});

// Try to decrement the semaphore. This succeeds if the count is still 1
// (meaning that runCriticalSection is not executing), and fails if the 
// current count is 0 (meaning that runCriticalSection is executing):
if (dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW) == 0) {
    // Success, semaphore count is now 0.
    // Start asynchronous operation.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //critical code
        [self runCriticalSection];
        // Increment the semaphore count (from 0 to 1), so that the next call
        // to applicationDidBecomeActive will start a new operation:
        dispatch_semaphore_signal(sema);
    });
}
like image 120
Martin R Avatar answered Nov 17 '22 20:11

Martin R