From 8784f76187eac00105389f853fd9dd6e9ec9d41a Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Mon, 11 Nov 2024 23:35:07 -0500 Subject: [PATCH] Fix DemandBuffer race (#3475) See also: https://github.com/CombineCommunity/CombineExt/pull/90 Co-authored-by: Stephen Celis --- .../Internal/Create.swift | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Sources/ComposableArchitecture/Internal/Create.swift b/Sources/ComposableArchitecture/Internal/Create.swift index 67e9355f1aff..4b47b677f866 100644 --- a/Sources/ComposableArchitecture/Internal/Create.swift +++ b/Sources/ComposableArchitecture/Internal/Create.swift @@ -21,27 +21,23 @@ // THE SOFTWARE. @preconcurrency import Combine -import Darwin +import Foundation final class DemandBuffer: @unchecked Sendable { private var buffer = [S.Input]() private let subscriber: S private var completion: Subscribers.Completion? private var demandState = Demand() - private let lock: os_unfair_lock_t + private let lock = NSRecursiveLock() init(subscriber: S) { self.subscriber = subscriber - self.lock = os_unfair_lock_t.allocate(capacity: 1) - self.lock.initialize(to: os_unfair_lock()) - } - - deinit { - self.lock.deinitialize(count: 1) - self.lock.deallocate() } func buffer(value: S.Input) -> Subscribers.Demand { + lock.lock() + defer { lock.unlock() } + precondition( self.completion == nil, "How could a completed publisher sent values?! Beats me 🤷‍♂️") @@ -55,6 +51,9 @@ final class DemandBuffer: @unchecked Sendable { } func complete(completion: Subscribers.Completion) { + lock.lock() + defer { lock.unlock() } + precondition( self.completion == nil, "Completion have already occurred, which is quite awkward 🥺")