Why can't we use a dispatch_sync on the current queue?

grand-central-dispatch, multithreading, objective-c, objective-c-blocks

Solution

I found this in the documentation (last chapter):

Do not call the dispatch_sync function from a task that is executing on the same queue that you pass to your function call. Doing so will deadlock the queue. If you need to dispatch to the current queue, do so asynchronously using the dispatch_async function.

Also, I followed the link that you provided and in the description of dispatch_sync I read this:

Calling this function and targeting the current queue results in deadlock.

So I don't think it's a problem with GCD, I think the only sensible approach is the one you invented after discovering the problem.

Problem

I ran into a scenario where I had a delegate callback which could occur on either the main thread or another thread, and I wouldn't know which until runtime (using `StoreKit.framework`). I also had UI code that I needed to update in that callback which needed to happen before the function executed, so my initial thought was to have a function like this: ``` -(void) someDelegateCallback:(id) sender { dispatch_sync(dispatch_get_main_queue(), ^{ // ui update code here }); // code here that depends upon the UI getting updated } ``` That works great, when it is executed on the background thread. However, when executed on the main thread, the program comes to a deadlock. That alone seems interesting to me, if I read the docs for `dispatch_sync` right, then I would expect it to just execute the block outright, not worrying about scheduling it into the runloop, as said here: As an optimization, this function invokes the block on the current thread when possible. But, that's not too big of a deal, it simply means a bit more typing, which lead me to this approach: ``` -(void) someDelegateCallBack:(id) sender { dispatch_block_t onMain = ^{ // update UI code here }; if (dispatch_get_current_queue() == dispatch_get_main_queue()) onMain(); else dispatch_sync(dispatch_get_main_queue(), onMain); } ``` However, this seems a bit backwards. Was this a bug in the making of GCD, or is there something that I am missing in the docs?

Original source

Related problems