What happens if you dispatch_async
a block of code on a queue that's currently blocked by it's own dispatch_sync
operation? Do they lock or will the blocked queue continue after the dispatch_sync
operation returns?
I have an object I created that manages access to a backing store (SQLite, in this case). It uses one concurrent
GCD queue and any other objects that want to access the information from the store will pass a request to the manager along with a block that will be executed asynchronously. The essence of what happens is this (not actual code):
- (void) executeRequest:(StoreRequest *)request withCompletionBlock:(void(^)(NSInteger result)block{
dispatch_queue_t currentContext = dispatch_get_current_queue();
dispatch_async(_storeQueue, ^{
NSInteger result = [_store executeRequest:request];
if (block){
dispatch_async(currentContext, ^{
block(result);
}
}
});
}
The real code is a bit more complex (I actually queue up and store requests/blocks/contexts to execute at the end of a run loop). I also use dispatch_barrier_async
for write requests to prevent concurrent read/writing. This all works fine, but in certain situations I also need to perform a synchronous request on the store. Now this request doesn't need to be performed before any queued up operations, but I do need the requesting queue blocked until the operation is performed. This can be easily done:
- (NSInteger) executeRequest:(StoreRequest *)request{
__block NSInteger result = 0;
dispatch_sync(_storeQueue, ^{
result = [_store executeRequest:request];
});
return result;
}
My question is this: What happens if a pending asynchronous operation placed before the synchronous operation dispatches a block of code asynchronously on the queue that is currently blocked by the synchronous dispatch. In other words, the above operation will dispatch its request at the end of the _store
queue and wait. But it's quite possible (even likely) that the operations in front of it include asynchronous dispatches back to the waiting queue (for other operations). Will this lock the threads? Since the queued blocks are dispatched asynchronously the _store
queue will never be blocked and therefore will finish, theoretically allowing the queue it's blocking to continue...but I'm not sure what happens with the blocks that were asynchronously dispatched or if dispatching anything to a block thread locks it up. I would assume that the blocked queue will continue, finish it's request and then the process the pending blocks, but I want to make sure.
Actually, now that I've written this all up, I'm pretty sure it'll work just fine, but I'm going to post this question anyway to make sure I'm not missing anything.