Replacement for dispatch_get_current_queue
The design of dispatch_get_current_queue is clearly problematic, as its docs indicate. I've heard rumors the function will be deprecated and removed soon. We currently use it for queue affinity asserts (for which it serves ably). Is there any plan on what it might be replaced with for this purpose? Adam
On 19 avr. 2013, at 22:48, Adam Ernst <adamjernst@fb.com> wrote:
The design of dispatch_get_current_queue is clearly problematic, as its docs indicate. I've heard rumors the function will be deprecated and removed soon.
We currently use it for queue affinity asserts (for which it serves ably). Is there any plan on what it might be replaced with for this purpose?
Take a look at dispatch_queue_get_specific and dispatch_queue_set_specific. Thomas
On Apr 20, 2013, at 4:13, Thomas Clement <tclementdev@gmail.com> wrote:
On 19 avr. 2013, at 22:48, Adam Ernst <adamjernst@fb.com> wrote:
The design of dispatch_get_current_queue is clearly problematic, as its docs indicate. I've heard rumors the function will be deprecated and removed soon. […] Take a look at dispatch_queue_get_specific and dispatch_queue_set_specific.
I have another use-case where objects can only be accessed from a single thread. For example: class MyClass { void set_foo (Foo* foo); … }; std::shared_ptr<MyClass> create_object () { dispatch_queue_t original_queue = dispatch_get_current_queue(); dispatch_retain(original_queue); std::shared_ptr<MyClass> res(new MyClass); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ Foo* foo = new Foo; // could be expensive dispatch_async(original_queue, ^{ res->set_foo(foo); dispatch_release(original_queue); }); }); return res; } One solution is to pass the current queue to create_object(), which normally would be the main queue, however, when running tests, it’s the testing framework that decides which queue a test executes in, so tests would have to create their own “inner” queue and run the actual code in that, so that they have a valid queue to pass to create_object(). Another solution would be to allow set_foo() to be executed on arbitrary threads. This however will make the implementation of MyClass harder, and it would basically only be for the benefit of our tests, so I don’t think this cost/extra complexity is justified. Probably the first solution is the best, but I’d be interested in hearing others’ take on this.
Allan, the dispatch_retain() here is not safe and can crash with a resurrection assertion if the queue in question has already been released by its owner. as the documentation says, you must not modify the queue returned by dispatch_get_current_queue() in any way, including retaining/releasing it or submitting blocks to it. If you need something like this, you must track & memory manage the queues of interest yourself, e.g. by passing them as parameters, or setting them as queue-specific context etc. Daniel On Apr 19, 2013, at 19:33, Allan Odgaard <lists+libdispatch@simplit.com> wrote:
On Apr 20, 2013, at 4:13, Thomas Clement <tclementdev@gmail.com> wrote:
On 19 avr. 2013, at 22:48, Adam Ernst <adamjernst@fb.com> wrote:
The design of dispatch_get_current_queue is clearly problematic, as its docs indicate. I've heard rumors the function will be deprecated and removed soon. […] Take a look at dispatch_queue_get_specific and dispatch_queue_set_specific.
I have another use-case where objects can only be accessed from a single thread.
For example:
class MyClass { void set_foo (Foo* foo); … };
std::shared_ptr<MyClass> create_object () { dispatch_queue_t original_queue = dispatch_get_current_queue(); dispatch_retain(original_queue);
std::shared_ptr<MyClass> res(new MyClass);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ Foo* foo = new Foo; // could be expensive dispatch_async(original_queue, ^{ res->set_foo(foo); dispatch_release(original_queue); }); });
return res; }
One solution is to pass the current queue to create_object(), which normally would be the main queue, however, when running tests, it’s the testing framework that decides which queue a test executes in, so tests would have to create their own “inner” queue and run the actual code in that, so that they have a valid queue to pass to create_object().
Another solution would be to allow set_foo() to be executed on arbitrary threads. This however will make the implementation of MyClass harder, and it would basically only be for the benefit of our tests, so I don’t think this cost/extra complexity is justified.
Probably the first solution is the best, but I’d be interested in hearing others’ take on this.
_______________________________________________ libdispatch-dev mailing list libdispatch-dev@lists.macosforge.org https://lists.macosforge.org/mailman/listinfo/libdispatch-dev
participants (4)
-
Adam Ernst
-
Allan Odgaard
-
Daniel A. Steffen
-
Thomas Clement