Skip to content

Commit 8784f76

Browse files
Fix DemandBuffer race (#3475)
See also: CombineCommunity/CombineExt#90 Co-authored-by: Stephen Celis <[email protected]>
1 parent 12268ed commit 8784f76

File tree

1 file changed

+8
-9
lines changed

1 file changed

+8
-9
lines changed

Sources/ComposableArchitecture/Internal/Create.swift

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,23 @@
2121
// THE SOFTWARE.
2222

2323
@preconcurrency import Combine
24-
import Darwin
24+
import Foundation
2525

2626
final class DemandBuffer<S: Subscriber>: @unchecked Sendable {
2727
private var buffer = [S.Input]()
2828
private let subscriber: S
2929
private var completion: Subscribers.Completion<S.Failure>?
3030
private var demandState = Demand()
31-
private let lock: os_unfair_lock_t
31+
private let lock = NSRecursiveLock()
3232

3333
init(subscriber: S) {
3434
self.subscriber = subscriber
35-
self.lock = os_unfair_lock_t.allocate(capacity: 1)
36-
self.lock.initialize(to: os_unfair_lock())
37-
}
38-
39-
deinit {
40-
self.lock.deinitialize(count: 1)
41-
self.lock.deallocate()
4235
}
4336

4437
func buffer(value: S.Input) -> Subscribers.Demand {
38+
lock.lock()
39+
defer { lock.unlock() }
40+
4541
precondition(
4642
self.completion == nil, "How could a completed publisher sent values?! Beats me 🤷‍♂️")
4743

@@ -55,6 +51,9 @@ final class DemandBuffer<S: Subscriber>: @unchecked Sendable {
5551
}
5652

5753
func complete(completion: Subscribers.Completion<S.Failure>) {
54+
lock.lock()
55+
defer { lock.unlock() }
56+
5857
precondition(
5958
self.completion == nil, "Completion have already occurred, which is quite awkward 🥺")
6059

0 commit comments

Comments
 (0)