Repository: ReactiveCocoa/ReactiveCocoa

Issue #2515: Deadlock on `buffer(...)`
Created: 2015-10-26T15:11:45Z
Hi. Sorry for giant stack trace. I've caught deadlock when I am try to bind property to signal in signal fire.
At short:

My timer is fired. (#68)
I assign new value to mutable property (#62)
Controller 1 observe change and decide to push Controller 2. (#19)
Controller 2 try to bind to the same signal as Controller 1 minded. (#12)
???.
Deadlock.

RAC version 4.0 alpha 1
#0  0x000000019ab34c6c in semaphore_wait_trap ()
#1  0x000000019ac0e97c in _os_semaphore_wait ()
#2  0x0000000101d4d428 in _dispatch_barrier_sync_f_slow ()
#3  0x0000000100abe5d0 in static SignalProducer.(buffer<A, B where ...> (SignalProducer<A, B>.Type) -> (Int) -> (SignalProducer<A, B>, (Event<A, B>) -> ())).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:154
#4  0x0000000100aa9050 in partial apply for static SignalProducer.(buffer<A, B where ...> (SignalProducer<A, B>.Type) -> (Int) -> (SignalProducer<A, B>, (Event<A, B>) -> ())).(closure #1) ()
#5  0x0000000100a9f424 in SignalProducer.startWithSignal<A, B where ...>((Signal<A, B>, Disposable) -> ()) -> () at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:247
#6  0x0000000100a63308 in protocol witness for SignalProducerType.startWithSignal<A where ...>((Signal<A.T, A.E>, Disposable) -> ()) -> () in conformance <A, B where ...> SignalProducer<A, B> at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:218
#7  0x0000000100aa95c4 in SignalProducerType<A where ...>.(lift<A><B, C where ...> (A) -> ((Signal<A.T, A.E>) -> Signal<B, C>) -> SignalProducer<B, C>).(closure #1) [inlined] at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:365
#8  0x0000000100aa9540 in partial apply for SignalProducerType<A where ...>.(lift<A><B, C where ...> (A) -> ((Signal<A.T, A.E>) -> Signal<B, C>) -> SignalProducer<B, C>).(closure #1) ()
#9  0x0000000100a9f424 in SignalProducer.startWithSignal<A, B where ...>((Signal<A, B>, Disposable) -> ()) -> () at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:247
#10 0x0000000100ae436c in static <~ infix<A where ...> (A, SignalProducer<A.Value, NoError>) -> Disposable at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Property.swift:232
#11 0x000000010013c58c in Store.bindProperty<A, B><C>(MutableProperty<C>, withLens : (A, (B) -> ()) -> C) -> () at /Users/project/src/Store.swift:38
#12 0x000000010013175c in AddNewLockErrorViewController.store.didset at /Users/project/src/add lock/AddNewLockErrorViewController.swift:45
#13 0x00000001001318e0 in AddNewLockErrorViewController.store.setter ()
#14 0x000000010012feb0 in AddNewLockScanningContoller.prepareForSegue(UIStoryboardSegue, sender : AnyObject?) -> () at /Users/project/src/add lock/AddNewLockSpinnerViewController.swift:53
#15 0x000000010013000c in @objc AddNewLockScanningContoller.prepareForSegue(UIStoryboardSegue, sender : AnyObject?) -> () ()
#16 0x000000018b255c78 in -[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] ()
#17 0x000000018b255ae0 in -[UIStoryboardSegueTemplate _perform:] ()
#18 0x000000018aecb6a8 in -[UIViewController performSegueWithIdentifier:sender:] ()
#19 0x0000000100130f04 in AddNewLockScanningContoller.(viewDidAppear(AddNewLockScanningContoller) -> (Bool) -> ()).(closure #3) at /Users/project/src/add lock/AddNewLockSpinnerViewController.swift:48
#20 0x000000010012ab30 in thunk ()
#21 0x0000000100af1018 in static Event.(sink<A, B where ...> (Event<A, B>.Type) -> (error : (B) -> ()?, completed : () -> ()?, interrupted : () -> ()?, next : (A) -> ()?) -> (Event<A, B>) -> ()).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Event.swift:108
#22 0x0000000100aeff78 in partial apply for static Event.(sink<A, B where ...> (Event<A, B>.Type) -> (error : (B) -> ()?, completed : () -> ()?, interrupted : () -> ()?, next : (A) -> ()?) -> (Event<A, B>) -> ()).(closure #1) ()
#23 0x0000000100a744bc in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#24 0x0000000100ac1a78 in SignalProducer.(startWithSignal<A, B where ...> (SignalProducer<A, B>) -> ((Signal<A, B>, Disposable) -> ()) -> ()).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:238
#25 0x0000000100a744bc in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#26 0x0000000100aef7bc in sendNext<A, B where ...> ((Event<A, B>) -> (), A) -> () at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Event.swift:178
#27 0x0000000100a7b21c in SignalType<A where ...>.(take<A where ...> (A) -> (Int) -> Signal<A.T, A.E>).(closure #1).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:600
#28 0x0000000100a70a00 in partial apply for SignalType<A where ...>.(take<A where ...> (A) -> (Int) -> Signal<A.T, A.E>).(closure #1).(closure #1) ()
#29 0x0000000100a744bc in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#30 0x0000000100ac1a78 in SignalProducer.(startWithSignal<A, B where ...> (SignalProducer<A, B>) -> ((Signal<A, B>, Disposable) -> ()) -> ()).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:238
#31 0x0000000100a744bc in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#32 0x0000000100a76720 in SignalType<A where ...>.(map<A><B where ...> (A) -> ((A.T) -> B) -> Signal<B, A.E>).(closure #1).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:212
#33 0x0000000100a71f60 in partial apply for SignalType<A where ...>.(map<A><B where ...> (A) -> ((A.T) -> B) -> Signal<B, A.E>).(closure #1).(closure #1) ()
#34 0x0000000100a74394 in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#35 0x0000000100ac1a78 in SignalProducer.(startWithSignal<A, B where ...> (SignalProducer<A, B>) -> ((Signal<A, B>, Disposable) -> ()) -> ()).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:238
#36 0x0000000100a74394 in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#37 0x0000000100aef7bc in sendNext<A, B where ...> ((Event<A, B>) -> (), A) -> () at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Event.swift:178
#38 0x0000000100a76cc4 in SignalType<A where ...>.(filter<A where ...> (A) -> ((A.T) -> Bool) -> Signal<A.T, A.E>).(closure #1).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:235
#39 0x0000000100a71d90 in partial apply for SignalType<A where ...>.(filter<A where ...> (A) -> ((A.T) -> Bool) -> Signal<A.T, A.E>).(closure #1).(closure #1) ()
#40 0x0000000100a74394 in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#41 0x0000000100ac1a78 in SignalProducer.(startWithSignal<A, B where ...> (SignalProducer<A, B>) -> ((Signal<A, B>, Disposable) -> ()) -> ()).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:238
#42 0x0000000100ac0930 in static SignalProducer.(buffer<A, B where ...> (SignalProducer<A, B>.Type) -> (Int) -> (SignalProducer<A, B>, (Event<A, B>) -> ())).(closure #2).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:186
#43 0x0000000101d41d30 in _dispatch_client_callout ()
#44 0x0000000101d4d88c in _dispatch_barrier_sync_f_invoke ()
#45 0x0000000100ac01bc in static SignalProducer.(buffer<A, B where ...> (SignalProducer<A, B>.Type) -> (Int) -> (SignalProducer<A, B>, (Event<A, B>) -> ())).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:189
#46 0x0000000100aef7bc in sendNext<A, B where ...> ((Event<A, B>) -> (), A) -> () at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Event.swift:178
#47 0x0000000100ae51c8 in MutableProperty.value.setter at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Property.swift:102
#48 0x0000000100a63894 in protocol witness for MutablePropertyType.value.setter in conformance <A> MutableProperty<A> at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Property.swift:99
#49 0x0000000100aeb344 in static (<~ infix<A where ...> (A, Signal<A.Value, NoError>) -> Disposable).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Property.swift:204
#50 0x0000000100a74394 in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#51 0x0000000100ac1a78 in SignalProducer.(startWithSignal<A, B where ...> (SignalProducer<A, B>) -> ((Signal<A, B>, Disposable) -> ()) -> ()).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:238
#52 0x0000000100a74394 in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#53 0x0000000100a76720 in SignalType<A where ...>.(map<A><B where ...> (A) -> ((A.T) -> B) -> Signal<B, A.E>).(closure #1).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:212
#54 0x0000000100a71f60 in partial apply for SignalType<A where ...>.(map<A><B where ...> (A) -> ((A.T) -> B) -> Signal<B, A.E>).(closure #1).(closure #1) ()
#55 0x0000000100a744bc in Signal.(init<A, B where ...> (Signal<A, B>.Type) -> (((Event<A, B>) -> ()) -> Disposable?) -> Signal<A, B>).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Signal.swift:63
#56 0x0000000100ac1a78 in SignalProducer.(startWithSignal<A, B where ...> (SignalProducer<A, B>) -> ((Signal<A, B>, Disposable) -> ()) -> ()).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:238
#57 0x0000000100ac0a40 in static SignalProducer.(buffer<A, B where ...> (SignalProducer<A, B>.Type) -> (Int) -> (SignalProducer<A, B>, (Event<A, B>) -> ())).(closure #2).(closure #1) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:186
#58 0x0000000101d41d30 in _dispatch_client_callout ()
#59 0x0000000101d4d88c in _dispatch_barrier_sync_f_invoke ()
#60 0x0000000100ac01bc in static SignalProducer.(buffer<A, B where ...> (SignalProducer<A, B>.Type) -> (Int) -> (SignalProducer<A, B>, (Event<A, B>) -> ())).(closure #2) at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/SignalProducer.swift:189
#61 0x0000000100aef7bc in sendNext<A, B where ...> ((Event<A, B>) -> (), A) -> () at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Event.swift:178
#62 0x0000000100ae51c8 in MutableProperty.value.setter at /Users/project/Carthage/Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/Swift/Property.swift:102
#63 0x000000010013bfd0 in Store.(dispatch in _B476A900240ACFD9431014A74E83EFE4)<A, B>(B) -> () at /Users/project/src/Store.swift:28
#64 0x000000010013c9d4 in partial apply ()
#65 0x00000001001243cc in thunk ()
#66 0x00000001001240c8 in (lens(AddNewLock.State, dispatch : (AddNewLock.Action) -> ()) -> LockScannerService.ServiceModel).(closure #2) at /Users/project/src/add lock/BluetoothLockScaner.swift:20
#67 0x000000010012298c in LockScannerService.timerFired() -> () at /Users/project/src/add lock/BluetoothLockScaner.swift:86
#68 0x00000001001229e4 in @objc LockScannerService.timerFired() -> () ()
#69 0x0000000186550324 in __NSFireTimer ()
#70 0x00000001855c8c9c in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#71 0x00000001855c8940 in __CFRunLoopDoTimer ()
#72 0x00000001855c6054 in __CFRunLoopRun ()
#73 0x00000001854f4dc0 in CFRunLoopRunSpecific ()
#74 0x0000000190648088 in GSEventRunModal ()
#75 0x000000018abcef44 in UIApplicationMain ()
#76 0x00000001000c8288 in main at /Users/project/support/main.m:14
#77 0x000000019aa328b8 in start ()

Duplicate issue #2643: freeze on iOS using signalproducer buffer combined with a bind on mutableproperty
Created: 2016-01-05T08:31:39Z
It does not crash, it just simply puts my application into a freezed state, unable to debug.
I have tested it on my simulator and device (both iPhone 6, iOS9.2)
Ive broken down the code to a simple example
struct A {
    let buffer = SignalProducer<String,NoError>.buffer()
    let mp = MutableProperty<String?>(nil)

    init() {
        mp <~ buffer.0.map(Optional.init)
    }
}

struct B {
    let buffer = SignalProducer<String,NoError>.buffer()
}


let a = A()
let b = B()

func result(value:String?) {
    print(value) // prints the value
    a.buffer.0.start(b.buffer.1)
    print("freezed") // does not get printed
}

a.mp.producer
    .ignoreNil()
    .startWithNext(result)

// if the stream above is swapped by this line it works as expected
//a.buffer.0.startWithNext(result)

a.buffer.1.sendNext("hello")

Closing comment (2016-01-07T22:39:06Z): This is the same as #2515.