Skip to content

Commit 5d13e52

Browse files
committed
Fixed a data race in CompositeDisposable.add.
The disposable array can be cleared at any time, since the disposal may happen after checking `isDisposed` but before accessing `disposables`.
1 parent e845bdd commit 5d13e52

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

Sources/Disposable.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,19 @@ public final class CompositeDisposable: Disposable {
170170
/// `disposable` is `nil`.
171171
@discardableResult
172172
public func add(_ disposable: Disposable?) -> Disposable? {
173-
if isDisposed {
174-
disposable?.dispose()
173+
guard let disposable = disposable else { return nil }
174+
guard !isDisposed else {
175+
disposable.dispose()
175176
return nil
176177
}
177178

178-
return disposable.flatMap { disposable in
179-
return disposables.modify { disposables in
180-
let token = disposables!.insert(disposable)
181-
return ActionDisposable { [weak self] in
182-
self?.disposables.modify {
183-
$0?.remove(using: token)
184-
}
179+
return disposables.modify { disposables in
180+
guard disposables != nil else { return nil }
181+
182+
let token = disposables!.insert(disposable)
183+
return ActionDisposable { [weak self] in
184+
self?.disposables.modify {
185+
$0?.remove(using: token)
185186
}
186187
}
187188
}

0 commit comments

Comments
 (0)