-
-
Save steipete/1205760 to your computer and use it in GitHub Desktop.
// checks if already in current queue, prevents deadlock | |
void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_block_t block) { | |
if (dispatch_get_current_queue() == queue) { | |
block(); | |
}else { | |
dispatch_sync(queue, block); | |
} | |
} |
"When called outside of the context of a submitted block, this function returns the default concurrent queue". The default concurrent queue is not the main queue. Thus the warning about don't use it with the main_queue (dispatch_get_main_queue() != dispatch_get_current_queue())
I removed the dispatch_async_reentrant, as @MSch pointed out, this may lead to bugs as you expect async to run after the current block.
dispatch_get_current_queue, from the docs (iOS 5 Docs at least):
"When called from outside of the context of a submitted block, this function returns the main queue if the call is executed from the main thread. If the call is made from any other thread, this function returns the default concurrent queue."
Where is your excerpt from? I know I used a similar function in a project with the main queue and it worked.
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/dispatch_set_target_queue.3.html
http://developer.apple.com/library/iOS/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
http://stackoverflow.com/questions/4942686/how-to-know-where-queue-am-i-main-queue-or-not
Where do you find this? Would be great if they changed this...
I'm not quite sure if this is the correct solution. I mostly use gcd to replace old, slow locking with @synchronized. However, if you don't perfectly isolate calls, a second call for dispatch_sync/async with the same queue creates an instand deadlock. Using those reentrant wrappers check which block is current, and prevent deadlocking.
Just wondering why there's nothing out-of-the-box in libdispatch. Am I missing sth?