Files
swift-mirror/stdlib/public/Concurrency/ExecutorImpl.swift
Alastair Houghton 629d708577 [Concurrency] Add more availability tests.
Some additional availability tests required.
2025-11-11 17:59:29 +00:00

145 lines
5.1 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Implementations of the *Impl functions that bridge to Swift.
//
// These are separate from the functions in ExecutorBridge.swift so that we
// can omit this file from the Embedded Swift version of Concurrency for now.
// (This means that the existing co-operative executor will still work.)
//
//===----------------------------------------------------------------------===//
import Swift
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_asyncMainDrainQueueImpl")
internal func drainMainQueue() {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.3, *) {
try! MainActor.executor.run()
_exit(result: 0)
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_asyncMainDrainQueue() not supported with task-to-thread")
#endif
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_donateThreadToGlobalExecutorUntilImpl")
internal func donateToGlobalExecutor(
condition: @convention(c) (_ ctx: UnsafeMutableRawPointer) -> CBool,
context: UnsafeMutableRawPointer
) {
if #available(StdlibDeploymentTarget 6.3, *) {
if let runnableExecutor = Task.defaultExecutor as? RunLoopExecutor {
try! runnableExecutor.runUntil { unsafe Bool(condition(context)) }
} else {
fatalError("Global executor does not support thread donation")
}
} else {
fatalError("this should never happen")
}
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_getMainExecutorImpl")
internal func getMainExecutor() -> UnownedSerialExecutor {
if #available(StdlibDeploymentTarget 6.3, *) {
return unsafe _getMainExecutorAsSerialExecutor()
} else {
fatalError("this should never happen")
}
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_enqueueMainExecutorImpl")
internal func enqueueOnMainExecutor(job unownedJob: UnownedJob) {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.3, *) {
MainActor.executor.enqueue(unownedJob)
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_enqueueMainExecutor() not supported for task-to-thread")
#endif
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_enqueueGlobalImpl")
internal func enqueueOnGlobalExecutor(job unownedJob: UnownedJob) {
if #available(StdlibDeploymentTarget 6.3, *) {
Task.defaultExecutor.enqueue(unownedJob)
} else {
fatalError("this should never happen")
}
}
#if !$Embedded
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_enqueueGlobalWithDelayImpl")
internal func enqueueOnGlobalExecutor(delay: CUnsignedLongLong,
job unownedJob: UnownedJob) {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.3, *) {
Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob),
after: .nanoseconds(delay),
clock: .continuous)
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_enqueueGlobalWithDelay() not supported for task-to-thread")
#endif
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_enqueueGlobalWithDeadlineImpl")
internal func enqueueOnGlobalExecutor(seconds: CLongLong,
nanoseconds: CLongLong,
leewaySeconds: CLongLong,
leewayNanoseconds: CLongLong,
clock: CInt,
job unownedJob: UnownedJob) {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
let delay = Duration.seconds(seconds) + Duration.nanoseconds(nanoseconds)
let leeway = Duration.seconds(leewaySeconds) + Duration.nanoseconds(leewayNanoseconds)
if #available(StdlibDeploymentTarget 6.3, *) {
switch clock {
case _ClockID.suspending.rawValue:
Task.defaultExecutor.asSchedulingExecutor!.enqueue(
ExecutorJob(unownedJob),
after: delay,
tolerance: leeway,
clock: .suspending
)
case _ClockID.continuous.rawValue:
Task.defaultExecutor.asSchedulingExecutor!.enqueue(
ExecutorJob(unownedJob),
after: delay,
tolerance: leeway,
clock: .continuous
)
default:
fatalError("Unknown clock ID \(clock)")
}
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_enqueueGlobalWithDeadline() not supported for task-to-thread")
#endif
}
#endif