> On Feb 27, 2017, at 10:53, Ole Begemann via swift-users 
> <swift-users@swift.org> wrote:
> 
> On 27/02/2017 19:34, Nate Chandler via swift-users wrote:
>> Hi Ole,
>> 
>> A quick follow-up--are you suggesting calling withExtendedLifetime
>> inside the closure passed to async, as below?
>> 
>> class AsyncHandle {
>> 
>>    let handle: Handle
>> 
>>    deinit {
>>        let handle: Handle = self.handle
>>        q.async {
>>            withExtendedLifetime(handle) {}
>>        }
>>    }
>> }
> 
> Yes, that's what I'm suggesting. Sorry I didn't make that clear before. Since 
> you mentioned that you couldn't use the stdlib's _fixLifetime function, I 
> just wanted to point out that there is a public function in the stdlib for 
> this purpose.
> 
>> If so, it seems that that may be a final answer to (3).  It does raise
>> an additional question, however:
>> 
>> (6) Would we expect calling withExtendedLifetime to have different
>> behavior from calling an @inline(never) function from a closure enqueued
>> async from deinit?
> 
> Yeah, I don't know the answer, sorry.

I'm not an optimizer person, but expecting '@inline(never)' to mean anything 
other than "don't inline this" is probably set for failure. The optimizer is 
still allowed to look at the body of the function. withExtendedLifetime is 
implemented more carefully to prevent eliding the capture.

That said, if you're not on when the outer deinit gets called 'q', you still 
have a raceā€”it's possible that 'q' will execute the block you give it before 
the deinitializer exits! I don't think there's a good way to avoid this other 
than to make 'handle' optional (or ImplicitlyUnwrappedOptional) and explicitly 
set it to nil before enqueuing the "deallocation block".

Jordan

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to