Hello. In the code below, I'm using @_inheritActorContext
. In this code, the presence or absence of _ = self
results in different Executors and Queues within the Block. The same issue occurs even when using Task.init
instead of foo_2(_:)
.
Is this a bug?
import Foundation
@_silgen_name("swift_task_isOnExecutor")
public func _taskIsOnExecutor<Executor: SerialExecutor>(_ executor: Executor) -> Bool
final class MySerialExecutor: SerialExecutor {
private let queue: DispatchQueue = .init(label: "Hello")
func enqueue(_ job: consuming ExecutorJob) {
let job: UnownedJob = .init(job)
queue.async {
job.runSynchronously(on: self.asUnownedSerialExecutor())
}
}
func isSameExclusiveExecutionContext(other: MySerialExecutor) -> Bool {
queue == other.queue
}
}
actor MyActor {
private let executor: MySerialExecutor = .init()
nonisolated var unownedExecutor: UnownedSerialExecutor {
executor.asUnownedSerialExecutor()
}
func foo_1() async {
let executor: any SerialExecutor = self.executor
// await Task {
await foo_2 {
// ???
_ = self
// true or false, depending on whether `_ = self` is commented out or not
print(_taskIsOnExecutor(executor))
let libdispatch: UnsafeMutableRawPointer = dlopen("/usr/lib/system/introspection/libdispatch.dylib", RTLD_NOW)!
let symbol: UnsafeMutableRawPointer = dlsym(libdispatch, "dispatch_get_current_queue")!
typealias Function = @convention(c) () -> dispatch_queue_t
let dispatch_get_current_queue: Function = unsafeBitCast(symbol, to: Function.self)
let queue: DispatchQueue = dispatch_get_current_queue()
// "Hello" or "com.apple.root.default-qos.cooperative", depending on whether `_ = self` is commented out or not
print(queue.label)
}
// }.value
}
private func foo_2(@_inheritActorContext _ block: @Sendable () async -> Void) async {
await block()
}
}
@main
struct MyScript {
static func main() async {
let myActor: MyActor = .init()
await myActor.foo_1()
}
}