I want to send a byte stream using my peripheral class. So I'm asking myself if the queue is needed for thread safety or if it's safe to delete it to unlock the flow.
I have this following struct
private struct WriteWithoutResponseContext {
let data: Data
let characteristic: Characteristic
}
And this two attributes
private var writeWithoutResponseContextQueue = Queue<WriteWithoutResponseContext>()
private let writeWithoutResponseContextCachingDispatchQueue = DispatchQueue(label: "thread-safe-unsent-data-caching", attributes: .concurrent)
I'm using the queue with a barrier to make sure everything is blocked until I added it to the queue when canSendWriteWithoutResponse is false.
How do we know that peripheralIsReady is not happening between check of canSendWriteWithoutResponse and enqueueing of context?
func writeValueWithoutResponse(_ data: Data, for characteristic: Characteristic) {
if self.cbPeripheral.canSendWriteWithoutResponse {
self.cbPeripheral.writeValue(data, for: characteristic, type: .withoutResponse)
} else {
self.writeWithoutResponseContextCachingDispatchQueue.async(flags: .barrier) {
let context = WriteWithoutResponseContext(data: data, characteristic: characteristic)
self.writeWithoutResponseContextQueue.enqueue(context)
}
}
}
func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) {
self.writeWithoutResponseContextCachingDispatchQueue.sync {
if let unsentContext = self.writeWithoutResponseContextQueue.dequeue() {
self.cbPeripheral.writeValue(unsentContext.data, for: unsentContext.characteristic, type: .withoutResponse)
}
}
}