@@ -88,9 +88,9 @@ public final class Signal<Value, Error: Swift.Error> {
8888 // `updateLock` must be acquired, and should fail gracefully if the
8989 // signal has terminated.
9090 //
91- // - Check if the signal is terminating, and transition from `terminating `
92- // to `terminated` if it is. Deliver the termination event after the
93- // transitioning .
91+ // - Check if the signal is terminating. If it is, invoke `tryTerminate `
92+ // which transitions the state from `terminating` to `terminated`, and
93+ // delivers the termination event .
9494 //
9595 // Both `sendLock` and `updateLock` must be acquired. The check can be
9696 // relaxed, but the state must be checked again after the locks are
@@ -102,32 +102,37 @@ public final class Signal<Value, Error: Swift.Error> {
102102 // are intentionally allowed in the `terminating` checks below. As a
103103 // result, normal event deliveries need not acquire `updateLock`.
104104 // Nevertheless, this should not cause the termination event being
105- // sent multiple times, since `shouldReallyTerminate ` would not
106- // respond to false positives.
105+ // sent multiple times, since `tryTerminate ` would not respond to false
106+ // positives.
107107
108- /// Return the terminating state if the signal is terminating , or `nil`
109- /// otherwise.
108+ /// Try to terminate the signal.
110109 ///
111- /// Calling this method as a result of a false positive `terminating` check
112- /// is permitted. `nil` would be returned in this case.
110+ /// If the signal is alive or has terminated, it fails gracefully. In
111+ /// other words, calling this method as a result of a false positive
112+ /// `terminating` check is permitted.
113113 ///
114114 /// - note: The `updateLock` would be acquired.
115115 ///
116- /// - returns: The terminating state or `nil` .
116+ /// - returns: `true` if the attempt succeeds. `false` otherwise .
117117 @inline ( __always)
118- func shouldReallyTerminate ( ) -> TerminatingState < Value , Error > ? {
118+ func tryTerminate ( ) -> Bool {
119119 // Acquire `updateLock`. If the termination has still not yet been
120120 // handled, take it over and bump the status to `terminated`.
121121 signal. updateLock. lock ( )
122122
123123 if case let . terminating( state) = signal. state {
124124 signal. state = . terminated
125125 signal. updateLock. unlock ( )
126- return state
126+
127+ for observer in state. observers {
128+ observer. action ( state. event)
129+ }
130+
131+ return true
127132 }
128-
133+
129134 signal. updateLock. unlock ( )
130- return nil
135+ return false
131136 }
132137
133138 if event. isTerminating {
@@ -160,14 +165,12 @@ public final class Signal<Value, Error: Swift.Error> {
160165 if signal. sendLock. try ( ) {
161166 // Check whether the terminating state has been handled by a
162167 // concurrent sender. If not, handle it.
163- if let terminatingState = shouldReallyTerminate ( ) {
164- for observer in terminatingState. observers {
165- observer. action ( terminatingState. event)
166- }
167- }
168-
168+ let shouldDispose = tryTerminate ( )
169169 signal. sendLock. unlock ( )
170- signal. swapDisposable ( ) ? . dispose ( )
170+
171+ if shouldDispose {
172+ signal. swapDisposable ( ) ? . dispose ( )
173+ }
171174 }
172175 } else {
173176 signal. updateLock. unlock ( )
@@ -203,12 +206,8 @@ public final class Signal<Value, Error: Swift.Error> {
203206
204207 // Check if the status has been bumped to `terminating` due to a
205208 // concurrent or a recursive termination event.
206- if case . terminating = signal. state, let terminatingState = shouldReallyTerminate ( ) {
207- for observer in terminatingState. observers {
208- observer. action ( terminatingState. event)
209- }
210-
211- shouldDispose = true
209+ if case . terminating = signal. state {
210+ shouldDispose = tryTerminate ( )
212211 }
213212 }
214213
@@ -220,15 +219,7 @@ public final class Signal<Value, Error: Swift.Error> {
220219 // protected section.
221220 if !shouldDispose, case . terminating = signal. state {
222221 signal. sendLock. lock ( )
223-
224- if let terminatingState = shouldReallyTerminate ( ) {
225- for observer in terminatingState. observers {
226- observer. action ( terminatingState. event)
227- }
228-
229- shouldDispose = true
230- }
231-
222+ shouldDispose = tryTerminate ( )
232223 signal. sendLock. unlock ( )
233224 }
234225
0 commit comments