 	}
 
 	deinit {
-		if state.swap(nil) != nil {
-			// As the signal can deinitialize only when it has no observers attached,
-			// only the generator disposable has to be disposed of at this point.
+		// A signal can deinitialize only when it is not retained and has no
+		// active observers. So `state` need not be swapped.
+		//
+		// The generator disposable needs to be disposed of only if a `green` status
+		// is observed here, since `red` would mean it has already been disposed of,
+		// and `yellow` is impossible to be observed here.
+		if case .green = status {
 			generatorDisposable?.dispose()
 		}
 	}

	///                that will act as an event emitter for the signal.
	public init(_ generator: (Observer) -> Disposable?) {
		state = Atomic(SignalState())

		/// Holds the final signal state captured by a termination event. If it
		/// is set, the Signal should terminate as soon as possible. Implicitly
		/// protected by `state` and `sendLock`.
		var terminationState: SignalTerminationState<Value, Error>? = nil

		/// Used to track if the signal has terminated. Protected by `sendLock`.
		var terminated = false

		/// Used to ensure that events are serialized during delivery to observers.
		let sendLock = NSLock()
		sendLock.name = "org.reactivecocoa.ReactiveSwift.Signal"

		func terminate(with state: SignalTerminationState<Value, Error>) {
			state.send()
			terminated = true
			terminationState = nil
		}

		let observer = Observer { [weak self] event in
			guard let signal = self else {

				// the disposal would be delegated to the current sender, or
				// occasionally one of the senders waiting on `sendLock`.
				if let state = signal.state.swap(nil) {
					// Updates to `status` are implicitly synchronized against `sendLock`.
					// 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.generatorDisposable?.dispose()
					}
				}
			} else if let observers = signal.state.value?.observers {
				var shouldDispose = false

				signal.sendLock.lock()

				if case .green = 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 .yellow(state) = signal.status {
						state.send()
						signal.status = .red
						shouldDispose = true
					}
				}

				signal.sendLock.unlock()

				// Based on the implicit memory order, any updates to the
				// `terminationSnapshot` 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 let .yellow(state) = signal.status {
					signal.sendLock.lock()

					// The status 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 signal is still at `yellow`.
					if case .yellow = signal.status {
						state.send()
						signal.status = .red
						shouldDispose = true
					}

					signal.sendLock.unlock()
				}

				if shouldDispose {
