Explicitly retain timer source when scheduling tasks (#138)

Motivation:

When a task is scheduled using a `DispatchTimerSource` on a `NIOTSEventLoop`
the source is retain via a callback on the promise associated with the
scheduled task. This stops the source from deinit'd before the task is
run. However, the callback being added is an implementation details of
`Scheduled` and the retain cycle is incidental.

If that detail chnaged (such as in
https://github.com/apple/swift-nio/pull/2011) then tasks may not run and
the promise could be leaked.

Modifications:

- Explicitly add a retain cycle between the future and the timer source
  which is broken by the promise being completed and callbacks run.

Result:

The timer source is kept alive until the event fires.
This commit is contained in:
George Barnett 2022-01-12 10:37:50 +00:00 committed by GitHub
parent e7f5278a26
commit 8ab824b140
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 6 additions and 0 deletions

View File

@ -138,6 +138,12 @@ internal class NIOTSEventLoop: QoSEventLoop {
}
timerSource.resume()
// Create a retain cycle between the future and the timer source. This will be broken when the promise is
// completed by the event handler and this callback is run.
p.futureResult.whenComplete { _ in
timerSource.cancel()
}
return Scheduled(promise: p, cancellationTask: {
timerSource.cancel()
})