from Swift 5.9 Darwin Environment supports DIspatchQueue as SerialExecutor
However DispatchQueue's isolation check in Concurrency
is inconsistent.
I have a DispatchActor
like below.
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, visionOS 1.0, *)
actor DispatchActor {
let queue: _DispatchSerialExecutorQueue
init(queue: DispatchQueue) {
if let serial = queue as? _DispatchSerialExecutorQueue {
self.queue = serial
} else {
let delegate = DispatchQueue(label: queue.label, target: queue)
if let serial = delegate as? _DispatchSerialExecutorQueue {
self.queue = serial
} else {
fatalError()
}
}
}
nonisolated var unownedExecutor: UnownedSerialExecutor {
queue.asUnownedSerialExecutor()
}
}
This code evalute success
let mainDispatch = DispatchActor(queue: .main)
await withUnsafeContinuation{ continuation in
mainDispatch.queue.async {
continuation.resume()
// passes
mainDispatch.preconditionIsolated()
// passes
MainActor.shared.preconditionIsolated()
RunLoop.main.perform {
// passess
MainActor.shared.preconditionIsolated()
}
}
}
This make sense since in usual Darwin environment MainActor is MainRunLoop
and DispatchQueue.main
However, below the code evaluate failure.
let privateActor = DispatchActor(queue: DispatchWorkloop(label: "private"))
await withUnsafeContinuation{ continuation in
privateActor.queue.async {
continuation.resume()
// assert!
privateActor.preconditionIsolated()
}
}
let privateActor = DispatchActor(queue: DispatchQueue(label: "private"))
await withUnsafeContinuation{ continuation in
privateActor.queue.async {
continuation.resume()
// assert!
privateActor.preconditionIsolated()
}
}
I wonder if this behavior is intended, and if it is why?