@@ -81,12 +81,14 @@ private protocol _CoFutureCancellable: class {
8181///
8282public class CoFuture < Value> {
8383
84+ @usableFromInline internal typealias _Result = Result < Value , Error >
85+
8486private var resultState : Int
85- private var nodes : CallbackStack < Result < Value , Error > >
86- private var _result : Optional < Result < Value , Error > >
87- private var parent : UnownedCancellable ?
87+ private var nodes : CallbackStack < _Result >
88+ private var _result : Optional < _Result >
89+ private unowned(unsafe) var parent : _CoFutureCancellable ?
8890
89- @usableFromInline internal init ( _result: Result < Value , Error > ? ) {
91+ @usableFromInline internal init ( _result: _Result ? ) {
9092if let result= _result{
9193self . _result= result
9294 resultState= 1
@@ -99,14 +101,18 @@ public class CoFuture<Value> {
99101}
100102
101103deinit {
102- if !nodes. isEmpty{
103- nodes. finish ( with: . failure( CoFutureError . canceled) )
104- }
104+ if nodes. isEmpty{ return }
105+ nodes. finish ( with: . failure( CoFutureError . canceled) )
105106}
106107
107108}
108109
109110extension CoFuture : _CoFutureCancellable {
111+
112+ internal convenience init < T> ( parent: CoFuture < T > ) {
113+ self . init ( _result: nil )
114+ self . parent= parent
115+ }
110116
111117 /// Starts a new coroutine and initializes future with its result.
112118 ///
@@ -121,8 +127,9 @@ extension CoFuture: _CoFutureCancellable {
121127@inlinable public convenience init ( task: @escaping ( ) throws -> Value ) {
122128self . init ( _result: nil )
123129Coroutine . start {
124- let current = try ? Coroutine . current ( )
125- self . whenCanceled { current? . cancel ( ) }
130+ if let current= try ? Coroutine . current ( ) {
131+ self . whenCanceled ( current. cancel)
132+ }
126133self . setResult ( Result ( catching: task) )
127134}
128135}
@@ -140,31 +147,20 @@ extension CoFuture: _CoFutureCancellable {
140147 nodes. isClosed? _result: nil
141148}
142149
143- @usableFromInline internal func setResult( _ result: Result < Value , Error > ) {
144- guard atomicExchange ( & resultState, with: 1 ) == 0 else { return }
150+ @usableFromInline internal func setResult( _ result: _Result ) {
151+ if atomicExchange ( & resultState, with: 1 ) == 1 { return }
145152 _result= result
146153 parent= nil
147154 nodes. close ( ) ? . finish ( with: result)
148155}
149156
150157 // MARK: - Callback
151158
152- @usableFromInline internal typealias Callback = ( Result < Value , Error > ) -> Void
153-
154- @usableFromInline internal func addCallback( _ callback: @escaping Callback ) {
159+ @usableFromInline internal func addCallback( _ callback: @escaping ( _Result ) -> Void ) {
155160if !nodes. append ( callback) { _result. map ( callback) }
156161}
157162
158- internal func addChild< T> ( future: CoFuture < T > , callback: @escaping Callback ) {
159- future. parent= . init( cancellable: self )
160- addCallback ( callback)
161- }
162-
163163 // MARK: - cancel
164-
165- private struct UnownedCancellable {
166- unowned(unsafe)let cancellable : _CoFutureCancellable
167- }
168164
169165 /// Returns `true` when the current future is canceled.
170166@inlinable public var isCanceled : Bool {
@@ -176,11 +172,7 @@ extension CoFuture: _CoFutureCancellable {
176172
177173 /// Cancels the current future.
178174public func cancel( ) {
179- if let parent= parent{
180- parent. cancellable. cancel ( )
181- } else {
182- setResult ( . failure( CoFutureError . canceled) )
183- }
175+ parent? . cancel ( ) ?? setResult ( . failure( CoFutureError . canceled) )
184176}
185177
186178}