[swift-users] Postponing owned object deinitialization
Jordan Rose
jordan_rose at apple.com
Mon Feb 27 14:01:11 CST 2017
> On Feb 27, 2017, at 10:53, Ole Begemann via swift-users <swift-users at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170227/5c06eb61/attachment.html>
More information about the swift-users
mailing list