I'm trying to use a resource wrapper for a thread safe access. In my implementation, awaitedValue
field performs a synchronous read
of resource through a serial queue. For some reason, whenever I try to read this property, my app crashes with an error, which doesn't really make sense with synchronous code.
class ThreadsafeResource<T> {
private let accessorsQueue: DispatchQueue
private var resource: T
//MARK: Initializers
init(_ resource: T) {
self.resource = resource
self.accessorsQueue = DispatchQueue(label: "X")
}
//MARK: Synchronous access
var awaitedValue: T {
accessorsQueue.sync(flags: .inheritQoS) { // Point where my app crashes.
self.resource
}
}
}
I've tried reading it from both main
and global(.utility)
queues – same result. And Asynchronous calls to resource work fine.
The problem manifests itself when you supply the flags
. If you remove that, the problem goes away.
Looking at the stack trace, it’s failing in _syncHelper
, which declares the closure as escaping when it’s not really, AFAICT. This rendition of _syncHelper
is called when you supply flags
and it’s not empty.
I'll file a bug report, as it would seem to be incorrect for _syncHelper
to make that parameter as @escaping
.
For now, I'd suggest you simply remove the flags
parameter or consider a different synchronization mechanism.