I have been writing unit tests for #2654 and found a bug in ConnectableObservableAdapter:
- Multicast operator produces a
ConnectableObservableAdapter
- when you subscribe to it via
Observable interface, it evaluates lazySubject computed property to instantiate a Subject without synchronization
- this can cause the
makeSubject to be called more than once if you perform several calls to subscribe concurrently
- and if it's going to return different instances of
Subject, this means that some of the concurrent subscriptions will actually be looking at the wrong instance of Subject, which will be overwritten during the data race.
This setup will naturally occur if:
- you are doing
flatMap into a connectable observable concurrently
- if you use
refCount operator, subscribing concurrently
share(replay: 2+, scope: .whileConnected) because it's implemented via multicast + refCount
You can see the code that reproduces this issue here: https://github.com/isaac-weisberg/RxSwiftDeadlock/tree/connect-unsafe
I am going to provide a fix for this issue inside #2654 since it's required to make all the tests run successfully.