10

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

Boon
  • 40,656
  • 60
  • 209
  • 315
  • possible duplicate of [Alternatives to dispatch\_get\_current\_queue() for completion blocks in iOS 6?](http://stackoverflow.com/questions/13237417/alternatives-to-dispatch-get-current-queue-for-completion-blocks-in-ios-6) – Lord Zsolt May 30 '14 at 13:39
  • possible duplicate of [What GCD queue, main or not, am I running on?](http://stackoverflow.com/questions/4942686/what-gcd-queue-main-or-not-am-i-running-on) – lucianomarisi May 30 '14 at 13:43
  • It's not duplicate - I am trying to figure out the decision as to why Apple deprecate this call. – Boon May 31 '14 at 03:48
  • To think about the reason is good for tech guys deep more. why close it ? – Forrest Nov 28 '14 at 09:24
  • The reasons _why_ this function has been deprecated can be found in the relevant man page. A few of the reasons have been mentioned already in the answers, but not exhaustive. See https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dispatch_get_current_queue.3.html – CouchDeveloper Oct 04 '15 at 13:37

2 Answers2

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.

Community
  • 1
  • 1
ipmcc
  • 29,581
  • 5
  • 84
  • 147
  • 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 '14 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 '14 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 05 '15 at 09: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 05 '15 at 13:47
  • @ipmcc -[NSThread isMainThread] is NOT sufficient/authoritative to figure out if current queue is main queue. It may be not. – Marcin Jun 03 '16 at 09:25
  • 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 03 '16 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.

Al Zonke
  • 532
  • 6
  • 8