Reputation: 24750
I know that deadlock ensues if you call a sync
dispatch from another sync
dispatch on the same serial queue, but that is the only "known" cause of GCD deadlocks I've heard of.
I am using a global concurrent queue, so I'd expect sync
requests to not lead to deadlock. I have this code, which is using ASIHTTPRequest
:
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[self.networkQueue cancelAllOperations];
self.networkQueue=nil;
self.networkQueue=[ASINetworkQueue queue];
});
The idea was to try to speed up the cancelAllOperations
part, since that can take quite a long time if you have a couple thousands operations in the networkQueue
.
But when I call this code, deadlock ensues. If I take this block out of GCD and run it on the main thread, there is a delay while cancelAllOperations
runs, but it does complete without deadlock. When inside this dispatch, however, the app freezes and iOS eventually terminates the app.
Any help is appreciated.
Upvotes: 2
Views: 1622
Reputation: 64002
You have this slightly wrong.
Using dispatch_sync()
to enqueue a Block to the serial queue on which you're already running is guaranteed to deadlock.
Using dispatch_sync()
to enqueue a Block to the concurrent queue on which you're already running is quite likely to deadlock. You're relying on the queue almost immediately dequeueing the synchronous block, which may or may not happen depending on available resources.
You also seem to be misunderstanding the nature of the concurrency offered by the queue. Submitting [self.networkQueue cancelAllOperations];
to a concurrent queue is not going to speed it up -- that method call isn't sliced into various units of work on the queue. Instead, the entire Block that you've submitted -- all three lines there -- is one unit for the queue. It may run concurrently with other Blocks that you submit, but it cannot itself take advantage of any concurrency. You would have to split the work up yourself and submit each unit as a separate Block -- sending cancel
to each operation on the NSOperationQueue
, for example.
You should most likely be using dispatch_async()
for this.
Upvotes: 1