I have an objective-c class with some methods, which use a GCD queue to ensure that concurrent accesses to a resource take place serially (standard way to do this).
Some of these methods need to call other methods of the same class. So the locking mechanism needs to be re-entrant. Is there a standard way to do this?
At first, I had each of these methods use
dispatch_sync(my_queue, ^{
// Critical section
});
to synchronize accesses. As you know, when one of these methods calls another such method, a deadlock happens because the dispatch_sync call stops the current executing until that other block is executed, which can't be executed also, because execution on the queue is stopped. To solve this, I then used e.g. this method:
- (void) executeOnQueueSync:(dispatch_queue_t)queue : (void (^)(void))theBlock {
if (dispatch_get_current_queue() == queue) {
theBlock();
} else {
dispatch_sync(queue, theBlock);
}
}
And in each of my methods, I use
[self executeOnQueueSync:my_queue : ^{
// Critical section
}];
I do not like this solution, because for every block with a different return type, I need to write another method. Moreover, this problem looks very common to me and I think there should exist a nicer, standard solution for this.