Skip to content

isaac-weisberg/RxSwiftDeadlock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RxSwift repo issue #2653

How to deadlock in RxSwift:

Step 0:

  • Simple observable
let sharedSubscription = Observable.create { observer in
    observer.on(.next(3))
    return Disposables.create()
}
.share(replay: 1)

let sources = 0...50
let oneSource = Observable.zip(sources.map { _ in
    self.getSomeInfoFromNetwork()
        .flatMap { _ in
            self.sharedSubscription
        }
        .take(1)
})

Step 1:

  • TakeCount operator tries to emit completion

Step 2:

  • Zip catches completion and starts disposing of the source sequence

Step 3:

  • This disposal propagates up to ShareReplay1WhileConnected
  • And it tries to acquire a lock to unsubscribe

Step 4:

  • Meanwhile, on a separate thread
  • ShareReplay1WhileConnected is replaying an event, while being under its own lock

Step 5:

  • It propagates down to zip operator, trying to acquire a lock

Step 6:

  • It's a data race, so occasionally the processes can overlap, which can cause two threads to wait on each other.
  • More concurrent operations = exponentially higher chances of a deadlock.

And that's how RxSwift deadlocks.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages