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.
@synchronized
instead? – Yungyunick@synchronized
is a classic lock, not based on GCD/queues, and therefor, as I understand it, it is discouraged to use it for reasons of code simplicity and performance. The title of this question is hence misleading, because it contains "lock". What I mean is synchronizing access in a reentrant way with GDC/queues. I simply had no better words than saying "reentrant locking", because that is the name of the solution to the problem that most people know. – Eocene@synchronized
has the advantage of leading to simpler code for reentrant -whatever- (how to call this best?). Still, the locking mechanism behind it has less performance than the mechanism behind GCD queues. – Eocene