10

Why did Apple deprecate dispatch_get_current_queue? What's unsafe about this call?

5

2 Answers 2

16

dispatch_get_current_queue never really made sense in the first place. Here's why: There are a handful of "root" queues (one for each priority, and then the main queue). Every other queue ultimately ends up targeting one of these root queues. This means that, in the general case, there isn't a single answer to the question, "What queue am I running on?"

For instance, if you have queue B that targets queue A, then either A or B would be a reasonable answer to that question, for a block submitted to queue B. Furthermore, since all queues end up targeting one of the global/root queues, arguably the best answer would be "whatever root queue it ended up executing on", except that's not really useful to anyone, because it doesn't significantly differentiate anything.

In my experience, in most cases, what folks want from dispatch_get_current_queue is the answer to, "What queue was I initially submitted to?" However, by definition, whatever code submitted the block already knows what queue it was submitted to (because it's doing the submission). So arguably, if you needed to capture that information, you could trivially do so at enqueue time; you don't need dispatch_get_current_queue to answer that question. For these cases, dispatch_get_current_queue would just be a shortcut, and a flawed one at that (because of queue targeting.)

The other big class of cases is when you want to know if you're on the main queue. -[NSThread isMainThread] is sufficient/authoritative for that, so you don't need dispatch_get_current_queue for that either.

Another answerer also pointed out that dispatch_get_current_queue was frequently misused in an attempt to emulate recursive locking with GCD queues. It's not possible to reliably implement recursive locks in a queue based system because "queues aren't locks". I've written at some length about that particular situation in another answer.

6
  • 1
    Thank you - I am a bit lost at the concept of "queue B that targets queue A". What do you mean by a queue targeting another queue?
    – Boon
    May 30, 2014 at 19:48
  • 1
    See the docs for dispatch_set_target_queue(). When you create a new private queue, by default it targets the default priority global concurrent queue (i.e. dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)). You can change what it targets by using dispatch_set_target_queue(). This allows you to set up arbitrary hierarchies of queues.
    – ipmcc
    May 30, 2014 at 20:28
  • ok, each queue can have a target queue, so queues can be ordered in a tree, but it is a reasonable question on which queue I am which is a leaf?!
    – János
    May 5, 2015 at 9:03
  • As explained in my answer, if all you want to know is the "leaf" queue, that information is already available to you by virtue of submitting the block to that leaf queue. i.e. you can capture a reference to the queue in the block's closure before you submit it. I get that this is clunky, but in practice, needing to know what queue you're executing on is usually a "code smell" to begin with. Why don't you post a new question asking how to do whatever it is you're actually trying to do here?
    – ipmcc
    May 5, 2015 at 13:47
  • 1
    How kind of you to mention this bit of esoterica, and then not explain it for folks. In the vast majority of cases, it is sufficient & authoritative. It's insufficient when the main loop of your application is accomplished using dispatch_main() instead of the normal GUI frameworks. Realistically, the number of cases where you would use dispatch_main() and still have a requirement to know whether you were on the main queue is vanishingly rare. (The former typically being non-GUI processes, the latter typically being GUI apps, where certain things must happen on the main thread.)
    – ipmcc
    Jun 3, 2016 at 11:24
2

It might be connected with wrong method usage.

Here is quote from documentation:

Recommended for debugging and logging purposes only: The code must not make any assumptions about the queue returned, unless it is one of the global queues or a queue the code has itself created. The code must not assume that synchronous execution onto a queue is safe from deadlock if that queue is not the one returned by dispatch_get_current_queue().

Same situation was with setFlipped: in NSImage — Apple deprecated them, because programmers used it in "wrong" way:

The flipped property of an image was widely misunderstood and has been deprecated.

Not the answer you're looking for? Browse other questions tagged or ask your own question.