> On Sep 26, 2017, at 11:22 AM, Jean-Daniel via swift-evolution
> <[email protected]> wrote:
>
>> Le 26 sept. 2017 à 00:13, Adam Kemp <[email protected]> a écrit :
>>
>>> On Sep 25, 2017, at 3:04 PM, Jean-Daniel via swift-evolution
>>> <[email protected]> wrote:
>>>
>>>> Le 25 sept. 2017 à 21:42, John McCall via swift-evolution
>>>> <[email protected]> a écrit :
>>>>
>>>> This doesn't have to be the case, actually. The intrinsics as Chris
>>>> described them wouldn't be sufficient, but you could require a "current
>>>> queue" to be provided when kicking off an async function from scratch, as
>>>> well as any other "async-local" context information you wanted (e.g. QoS
>>>> and the other things that Dispatch tracks with attributes/flags that are
>>>> generally supposed to persist across an entire async operation).
>>>>
>>>
>>> My response was about the ‘implicitly’ part. I hope we will get a rich API
>>> that let us specify return queue, QoS and more, but how do you plan to
>>> fulfill the « current queue » requirement implicitly ?
>>
>> My earlier response to this thread both linked to a previous thread about
>> this and explained how C# does it. It will require some library support, but
>> it can be done, and IMO should be done. As I’ve stressed repeatedly,
>> async/await without this behavior will be very difficult to use correctly. I
>> really hope we don’t settle for that.
>
> In C#, the model is far simple as there is not concept of a single dispatch
> queue that can execute work on any thread. You can easily use TLS to store a
> default context. Each UI thread can have a context that dispatch completion
> on the message queue, but AFAIK,
> there is not DispatchQueue Local Storage yet.
There is, see dispatch_queue*_specific()
> Even something as simple as getting the current queue is not reliable (see
> dispatch_get_current_queue man page for details).
This is a sharp construct for clients, but not for the runtime / compiler that
can be taught how not to fall in the traps of this API.
Just to debunk myths, dispatch_get_current_queue() is VERY WELL defined, but
has two major issues: nesting & refcounting.
Nesting
Nesting refers to the fact that when you call code that takes a queue and a
callback, you may observe *another* queue:
run_something_and_call_me_back(arg1, arg2, on_queue, ^{
assert(dispatch_get_current_queue() == on_queue); // may crash
... my stuff ...
});
The reason is that run_something_and_call_me_back() may create a queue that
targets `on_queue` and then this private queue is what is returned which is
both unexpected and exposing internals of the implementation of
run_something_and_call_me_back() which is all wrong.
A corollary is that people attempting to implement recursive locking (which is
a bad idea in general anyway) with dispatch_get_current_queue() will fail
miserably.
Refcounting
Because dispatch has a notion of internal refcount, in ARC world, this will
crash most of the time:
dispatch_async(dispatch_queue_create_with_target("foo", NULL, NULL), ^{
__strong dispatch_queue cq = dispatch_get_current_queue(); // will usually
crash with a resurrection error
});
These two edges is why we deprecated this interface for humans.
1) A compiler though is not affected by the first issue because the context it
would capture would have to not be programatically accessible to clients
2) The Swift runtime can know to take "internal" refcounts when capturing this
hidden pointer and is not affected by the second problem either.
tl;dr: what is badly defined is allowing clients to get a pointer to the
current queue with a real +1, but that is WAY stronger than what the language
runtime needs.
> That’s why I’m saying it will be difficult to define a reasonable default
> context that can be used implicitly.
This is just not true. This is both easy and reasonable.
-Pierre
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution