Crash when chaining operations in different Tasks
Closed this issue · 2 comments
version: 1.8.2
Issue:
I have 2 methods: one to register to notifications on some characteristics, and the second to read init ble values.
Each method uses Task { do {} catch {} } blocks to send their ble command.
In that case, calling these two methods one after the other, leads to a crash in PeripheralContext.readCharacteristicValueExecutor:
This crash does not occurs if I merge the two methods into one Task { do {} catch {} } block.
=======================================
Here is the sample code with crash:
init() {
setupBindings()
setupNotifications()
readBleValues()
}
func setupBindings() {
peripheral?.characteristicValueUpdatedPublisher
.receive(on: RunLoop.main)
.filter { $0.uuid.uuidString == Uuids.battery.uuidString }
.sink { [weak self] characteristic in
....
}.store(in :&cancellables)
}
func setupNotifications() {
Task {
do {
try await self.peripheral?.setNotifyValue(true, forCharacteristicWithUUID: Uuids.battery, ofServiceWithUUID: mainSrv)
} catch {
...
}
}
func readBleValues() {
Task {
do {
try await peripheral?.readValue(forCharacteristicWithUUID: <another uuid>, ofServiceWithUUID: mainSrv) ==> crashes
} catch {
....
}
}
=======================================
without crash:
init() {
setupBindings()
initNotificationsAndReadValues()
}
func setupBindings() {
// no change, same as above
}
func initNotificationsAndReadValues() {
Task {
do {
try await self.peripheral?.setNotifyValue(true, forCharacteristicWithUUID: Uuids.battery, ofServiceWithUUID: mainSrv)
try await peripheral?.readValue(forCharacteristicWithUUID: <another uuid>, ofServiceWithUUID: mainSrv) ==> NO CRASHES
} catch {
...
}
}
Oh, interesting! While I was unable to reproduce this, I think I know why this might be happening. That flushable list is not thread safe. I'll attempt a blind fix.
Yes it does not occur systematically. But occurence might be enhanced by stressing out 2 similar characteristics