 /// The status of a `Signal`.
 private enum SignalStatus<Value, Error: Swift.Error> {
 	/// The `Signal` is alive.
-	case green
+	case alive
 
 	/// The `Signal` has received a termination event, and is about to be
 	/// terminated.
-	case yellow(SignalTerminationSnapshot<Value, Error>)
+	case terminating(SignalTerminationSnapshot<Value, Error>)
 
 	/// The `Signal` has terminated.
-	case red
+	case terminated
 }
 
 /// A snapshot of the state of a `Signal` when it receives a termination event.

					// So we do not need to guard it with an explicit lock.
					//
					// Specifically, senders are serialized by `sendLock`, and can react
					// to and bump the status to `red` only after they see the status
					// being `yellow`.
					//
					// `yellow` can happen only once, since `state` being swapped with
					// `nil` is a point of no return.
					//
					// Even in the case that both a previous sender and its successor see
					// `yellow`, the senders are still bound to the `sendLock`. So
					// whichever sender loses the battle of acquring `sendLock` is
					// guaranteed to be blocked by a status of `red`.
					signal.status = .yellow(SignalTerminationSnapshot(state: state, event: event))

					if signal.sendLock.try() {
						if case let .yellow(state) = signal.status {
							state.send()
							signal.status = .red
						}
						signal.sendLock.unlock()
						signal.swapDisposable()?.dispose()


				signal.sendLock.lock()

				if case .alive = signal.status {
					for observer in observers {
						observer.action(event)
					}

					// Check if a downstream consumer or a concurrent sender has
					// interrupted the signal.
					if case let .terminating(state) = signal.status {
						state.send()
						signal.status = .terminated
						shouldDispose = true
					}
				}

				signal.sendLock.unlock()

				// Based on the implicit memory order, any updates to `status` should
				// always be visible after `sendLock` is released. So we check it again
				// and handle the termination if it has not been taken over.
				if !shouldDispose, case .terminating = signal.status {
					signal.sendLock.lock()

					// The `terminating` check before acquring `sendLock` could be a false
					// positive, since it might race against other concurrent senders
					// until the lock acquisition above succeeds. So we have to check
					// again if the status is still `terminating`.
					if case let .terminating(state) = signal.status {
						state.send()
						signal.status = .terminated
						shouldDispose = true
					}

