JetForMe
(Rick M)
1
I've been working on this libmodbus wrapper, and I want to serialize accesses to the libmodbus context. I do so like this:
public
func
readRegister(fromDevice inDeviceID: Int, atAddress inAddr: Int)
async
throws
-> UInt16
{
try await withCheckedThrowingContinuation
{ inCont in
self.workQ.async
{
do
{
self.deviceID = inDeviceID // <-- capture of 'self' with non-sendable type 'MODBUSContext' in a `@Sendable` closure
let r = try self.readRegister(address: inAddr)
inCont.resume(returning: r)
}
catch (let e)
{
inCont.resume(throwing: e)
}
}
}
}
This method exists with in a final class MODBUSContext definition.
I went down the path of trying to make MODBUSContext conform to Sendable, but it turns out DispatchQueue doesn’t conform. So, I’m not sure how to clean this up. Any suggestions?
lukasa
(Cory Benfield)
2
Use @unchecked Sendable. If the only thing that doesn't conform is DispatchQueue, then you can tell the compiler to shut up: you know that DispatchQueue is actually thread-safe, so you can just mark your type appropriately.
1 Like
JetForMe
(Rick M)
3
Does that mean DispatchQueue should conform?
That is a strong word that infers moral obligation. I would say that; DispatchQueue safely meets the requirements of Sendable except one set of caveats; DispatchQueue.sync. If you avoid that and similar functions then the type is reasonable to use in an actor and in conjunction with existing systems.
JetForMe
(Rick M)
5
I mean "should" because it's extraordinarily common to use it in this manner, isn't it, to make an Actor? It should conform in order to relieve the burden on everyone using it like this.
But, maybe I'm Doing It Wrong.
While Swift concurrency does strongly discourage the use of thread-blocking patterns like DispatchQueue.sync, the method itself doesn't violate any sendability restrictions. And as long as the queue isn't backed by a width-limited queue, you won't get exhaustion deadlocks. You can, of course, get other kinds of deadlock if you call it while holding some other thread-exclusive resource. @rokhinip may be able to correct me here.
So DispatchQueue ought to be Sendable.
3 Likes
JetForMe
(Rick M)
7
For now, then, it should be enough to just declare conformance with an extension, right?
extension DispatchQueue : Sendable { }