diff --git a/RxSwift/Observables/Multicast.swift b/RxSwift/Observables/Multicast.swift index 3af68d29f..46f96c031 100644 --- a/RxSwift/Observables/Multicast.swift +++ b/RxSwift/Observables/Multicast.swift @@ -246,6 +246,12 @@ private final class ConnectableObservableAdapter: } } +enum RefCountSinkRunResult { + case alreadyDisposed + case nothingToDo + case connectionToCreate(SingleAssignmentDisposable) +} + private final class RefCountSink: Sink, ObserverType where ConnectableSource.Element == Observer.Element @@ -264,19 +270,34 @@ private final class RefCountSink Disposable { let subscription = parent.source.subscribe(self) - parent.lock.lock(); defer { self.parent.lock.unlock() } + + let runResult = parent.lock.withLock { () -> RefCountSinkRunResult in + connectionIdSnapshot = parent.connectionId - connectionIdSnapshot = parent.connectionId + if isDisposed { + return .alreadyDisposed + } - if isDisposed { - return Disposables.create() + if parent.count == 0 { + parent.count = 1 + let disposable = SingleAssignmentDisposable() + parent.connectableSubscription = disposable + return .connectionToCreate(disposable) + } else { + parent.count += 1 + return .nothingToDo + } } - if parent.count == 0 { - parent.count = 1 - parent.connectableSubscription = parent.source.connect() - } else { - parent.count += 1 + switch runResult { + case .nothingToDo: + break + case .alreadyDisposed: + return Disposables.create() + case .connectionToCreate(let singleAssignmentDisposable): + singleAssignmentDisposable.setDisposable( + parent.source.connect() + ) } return Disposables.create {