@@ -57,17 +57,14 @@ public final class Signal<Value, Error: Swift.Error> {
5757 }
5858
5959 if case . interrupted = event {
60- // Normally we disallow recursive events, but `interrupted` is
61- // kind of a special snowflake, since it can inadvertently be
62- // sent by downstream consumers.
60+ // Recursive events are generally disallowed. But `interrupted` is kind
61+ // of a special snowflake, since it can inadvertently be sent by
62+ // downstream consumers.
6363 //
64- // So we'll flag Interrupted events specially, and if it
65- // happened to occur while we're sending something else, we'll
66- // wait to deliver it.
67-
68-
69- // Clear the signal state to prevent new observers, but retain a copy of
70- // it.
64+ // So we would treat `interrupted` events specially. If it happens
65+ // to occur while the `sendLock` is acquired, the observer call-out and
66+ // the disposal would be delegated to the current sender, or
67+ // occasionally one of the senders waiting on `sendLock`.
7168 if let state = signal. state. swap ( nil ) {
7269 interruptedState. value = state
7370
@@ -95,6 +92,8 @@ public final class Signal<Value, Error: Swift.Error> {
9592 observer. action ( event)
9693 }
9794
95+ // Check if a downstream consumer or a concurrent sender has
96+ // interrupted the signal.
9897 if !isTerminating, let state = interruptedState. swap ( nil ) {
9998 for observer in state. observers {
10099 observer. sendInterrupted ( )
@@ -111,10 +110,10 @@ public final class Signal<Value, Error: Swift.Error> {
111110
112111 sendLock. unlock ( )
113112
114- // Based on the implicit memory order, any disposal of `interrupted`
115- // should always be visible after `sendLock` is released. So we
116- // check `interrupted` here again and handle the interruption if
117- // necessary .
113+ // Based on the implicit memory order, any updates to the
114+ // `interruptedState` should always be visible after `sendLock` is
115+ // released. So we check it again and handle the interruption if
116+ // it has not been taken over .
118117 if !shouldDispose && !terminated && !isTerminating, let state = interruptedState. swap ( nil ) {
119118 sendLock. lock ( )
120119
0 commit comments