mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[6.2][Concurrency][SE-review update] Task names update (#81132)
**Description**: This adds "task name" parameter to all task creating functions. This is done in a few ways, e.g. we can backdeploy this to 5.1 in APIs which do not accept the `TaskExecutor` but it they do we provide a version for 6.0+ etc. This was requested in the SE acceptable of this proposal [Acceptance post SE-0469](https://forums.swift.org/t/accepted-with-modifications-se-0469-task-naming/79438). This moves all these declarations to gyb since going through them one by one has become unmaintainable otherwise. **Scope/Impact**: All task creation APIs now gain a new task name parameter. **Risk:** Medium, changes existing APIs rather than adding "even more overloads" though this risk was discussed in the team and accepted. This has a potential to be source breaking it someone used Task.init and friends as function. **Testing**: CI testing, source compatibility suite testing **Reviewed by**: **Original PR:** - https://github.com/swiftlang/swift/pull/81107 build changes required for this - https://github.com/swiftlang/swift/pull/80984 **Radar:** --------- Co-authored-by: Kuba Mracek <mracek@apple.com>
This commit is contained in:
committed by
GitHub
parent
28360605e7
commit
c8a8183d26
@@ -1,5 +1,6 @@
|
||||
add_subdirectory(InternalShims)
|
||||
|
||||
gyb_expand(Task+init.swift.gyb Task+init.swift)
|
||||
gyb_expand(TaskGroup+addTask.swift.gyb TaskGroup+addTask.swift)
|
||||
gyb_expand(Task+immediate.swift.gyb Task+immediate.swift)
|
||||
|
||||
@@ -92,10 +93,10 @@ add_library(swift_Concurrency
|
||||
Task+TaskExecutor.swift
|
||||
TaskCancellation.swift
|
||||
TaskGroup.swift
|
||||
TaskGroup+Embedded.swift
|
||||
TaskLocal.swift
|
||||
TaskSleep.swift
|
||||
TaskSleepDuration.swift
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Task+init.swift"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/TaskGroup+addTask.swift"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Task+immediate.swift")
|
||||
|
||||
|
||||
@@ -27,15 +27,15 @@ function(set_if_arch_bitness var_name)
|
||||
"${SIA_ARCH}" STREQUAL "powerpc")
|
||||
set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE)
|
||||
elseif("${SIA_ARCH}" STREQUAL "x86_64" OR
|
||||
"${SIA_ARCH}" STREQUAL "amd64" OR
|
||||
"${SIA_ARCH}" STREQUAL "arm64" OR
|
||||
"${SIA_ARCH}" STREQUAL "arm64e" OR
|
||||
"${SIA_ARCH}" STREQUAL "aarch64" OR
|
||||
"${SIA_ARCH}" STREQUAL "powerpc64" OR
|
||||
"${SIA_ARCH}" STREQUAL "powerpc64le" OR
|
||||
"${SIA_ARCH}" STREQUAL "s390x" OR
|
||||
"${SIA_ARCH}" STREQUAL "riscv64" OR
|
||||
"${SIA_ARCH}" STREQUAL "wasm64")
|
||||
"${SIA_ARCH}" STREQUAL "amd64" OR
|
||||
"${SIA_ARCH}" STREQUAL "arm64" OR
|
||||
"${SIA_ARCH}" STREQUAL "arm64e" OR
|
||||
"${SIA_ARCH}" STREQUAL "aarch64" OR
|
||||
"${SIA_ARCH}" STREQUAL "powerpc64" OR
|
||||
"${SIA_ARCH}" STREQUAL "powerpc64le" OR
|
||||
"${SIA_ARCH}" STREQUAL "s390x" OR
|
||||
"${SIA_ARCH}" STREQUAL "riscv64" OR
|
||||
"${SIA_ARCH}" STREQUAL "wasm64")
|
||||
set("${var_name}" "${SIA_CASE_64_BIT}" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown architecture: ${SIA_ARCH}")
|
||||
|
||||
@@ -822,6 +822,7 @@ function(add_swift_target_library_single target name)
|
||||
IS_FRAGILE)
|
||||
set(SWIFTLIB_SINGLE_single_parameter_options
|
||||
ARCHITECTURE
|
||||
ARCHITECTURE_SUBDIR_NAME
|
||||
DEPLOYMENT_VERSION_IOS
|
||||
DEPLOYMENT_VERSION_OSX
|
||||
DEPLOYMENT_VERSION_TVOS
|
||||
@@ -888,6 +889,9 @@ function(add_swift_target_library_single target name)
|
||||
precondition(SWIFTLIB_SINGLE_SDK MESSAGE "Should specify an SDK")
|
||||
precondition(SWIFTLIB_SINGLE_ARCHITECTURE MESSAGE "Should specify an architecture")
|
||||
precondition(SWIFTLIB_SINGLE_INSTALL_IN_COMPONENT MESSAGE "INSTALL_IN_COMPONENT is required")
|
||||
if (NOT SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME)
|
||||
set(SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME "${SWIFTLIB_SINGLE_ARCHITECTURE}")
|
||||
endif()
|
||||
|
||||
if(NOT SWIFTLIB_SINGLE_SHARED AND
|
||||
NOT SWIFTLIB_SINGLE_STATIC AND
|
||||
@@ -903,12 +907,12 @@ function(add_swift_target_library_single target name)
|
||||
|
||||
# Determine the subdirectory where this library will be installed.
|
||||
set(SWIFTLIB_SINGLE_SUBDIR
|
||||
"${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}/${SWIFTLIB_SINGLE_ARCHITECTURE}")
|
||||
"${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}/${SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME}")
|
||||
|
||||
# macCatalyst ios-like builds are installed in the maccatalyst/x86_64 directory
|
||||
if(maccatalyst_build_flavor STREQUAL "ios-like")
|
||||
set(SWIFTLIB_SINGLE_SUBDIR
|
||||
"${SWIFT_SDK_MACCATALYST_LIB_SUBDIR}/${SWIFTLIB_SINGLE_ARCHITECTURE}")
|
||||
"${SWIFT_SDK_MACCATALYST_LIB_SUBDIR}/${SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME}")
|
||||
endif()
|
||||
|
||||
if ("${SWIFTLIB_SINGLE_BOOTSTRAPPING}" STREQUAL "")
|
||||
@@ -1033,6 +1037,7 @@ function(add_swift_target_library_single target name)
|
||||
${SWIFTLIB_SINGLE_LINK_LIBRARIES}
|
||||
SDK ${SWIFTLIB_SINGLE_SDK}
|
||||
ARCHITECTURE ${SWIFTLIB_SINGLE_ARCHITECTURE}
|
||||
ARCHITECTURE_SUBDIR_NAME ${SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME}
|
||||
MODULE_NAME ${module_name}
|
||||
MODULE_DIR ${SWIFTLIB_SINGLE_MODULE_DIR}
|
||||
COMPILE_FLAGS ${SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS}
|
||||
@@ -1058,9 +1063,9 @@ function(add_swift_target_library_single target name)
|
||||
|
||||
# If there were any swift sources, then a .swiftmodule may have been created.
|
||||
# If that is the case, then add a target which is an alias of the module files.
|
||||
set(VARIANT_SUFFIX "-${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE}")
|
||||
set(VARIANT_SUFFIX "-${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME}")
|
||||
if(maccatalyst_build_flavor STREQUAL "ios-like")
|
||||
set(VARIANT_SUFFIX "-${SWIFT_SDK_MACCATALYST_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE}")
|
||||
set(VARIANT_SUFFIX "-${SWIFT_SDK_MACCATALYST_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE_SUBDIR_NAME}")
|
||||
endif()
|
||||
|
||||
if(NOT "${SWIFTLIB_SINGLE_MODULE_TARGETS}" STREQUAL "" AND NOT "${swift_module_dependency_target}" STREQUAL "")
|
||||
|
||||
@@ -50,7 +50,7 @@ function(handle_swift_sources
|
||||
sourcesvar externalvar name)
|
||||
cmake_parse_arguments(SWIFTSOURCES
|
||||
"IS_MAIN;IS_STDLIB;IS_STDLIB_CORE;IS_SDK_OVERLAY;EMBED_BITCODE;STATIC;NO_LINK_NAME;IS_FRAGILE;ONLY_SWIFTMODULE;NO_SWIFTMODULE"
|
||||
"SDK;ARCHITECTURE;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS;MACCATALYST_BUILD_FLAVOR;BOOTSTRAPPING;INSTALL_BINARY_SWIFTMODULE"
|
||||
"SDK;ARCHITECTURE;ARCHITECTURE_SUBDIR_NAME;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS;MACCATALYST_BUILD_FLAVOR;BOOTSTRAPPING;INSTALL_BINARY_SWIFTMODULE"
|
||||
"DEPENDS;COMPILE_FLAGS;MODULE_NAME;MODULE_DIR;ENABLE_LTO"
|
||||
${ARGN})
|
||||
translate_flag(${SWIFTSOURCES_IS_MAIN} "IS_MAIN" IS_MAIN_arg)
|
||||
@@ -83,6 +83,9 @@ function(handle_swift_sources
|
||||
precondition(SWIFTSOURCES_SDK "Should specify an SDK")
|
||||
precondition(SWIFTSOURCES_ARCHITECTURE "Should specify an architecture")
|
||||
precondition(SWIFTSOURCES_INSTALL_IN_COMPONENT "INSTALL_IN_COMPONENT is required")
|
||||
if (NOT SWIFTSOURCES_ARCHITECTURE_SUBDIR_NAME)
|
||||
set(SWIFTSOURCES_ARCHITECTURE_SUBDIR_NAME "${SWIFTSOURCES_ARCHITECTURE}")
|
||||
endif()
|
||||
|
||||
# Clear the result variable.
|
||||
set("${dependency_target_out_var_name}" "" PARENT_SCOPE)
|
||||
@@ -108,12 +111,12 @@ function(handle_swift_sources
|
||||
endif()
|
||||
|
||||
if(swift_sources)
|
||||
set(objsubdir "/${SWIFTSOURCES_SDK}/${SWIFTSOURCES_ARCHITECTURE}")
|
||||
set(objsubdir "/${SWIFTSOURCES_SDK}/${SWIFTSOURCES_ARCHITECTURE_SUBDIR_NAME}")
|
||||
|
||||
get_maccatalyst_build_flavor(maccatalyst_build_flavor
|
||||
"${SWIFTSOURCES_SDK}" "${SWIFTSOURCES_MACCATALYST_BUILD_FLAVOR}")
|
||||
if(maccatalyst_build_flavor STREQUAL "ios-like")
|
||||
set(objsubdir "/MACCATALYST/${SWIFTSOURCES_ARCHITECTURE}")
|
||||
set(objsubdir "/MACCATALYST/${SWIFTSOURCES_ARCHITECTURE_SUBDIR_NAME}")
|
||||
endif()
|
||||
|
||||
get_bootstrapping_path(lib_dir
|
||||
|
||||
@@ -129,7 +129,6 @@ set(SWIFT_RUNTIME_CONCURRENCY_SWIFT_SOURCES
|
||||
Task+TaskExecutor.swift
|
||||
TaskCancellation.swift
|
||||
TaskGroup.swift
|
||||
TaskGroup+Embedded.swift
|
||||
DiscardingTaskGroup.swift
|
||||
TaskLocal.swift
|
||||
TaskSleep.swift
|
||||
@@ -206,6 +205,12 @@ set(LLVM_OPTIONAL_SOURCES
|
||||
DispatchGlobalExecutor.cpp
|
||||
)
|
||||
|
||||
set(SWIFT_CONCURRENCY_GYB_SOURCES
|
||||
Task+init.swift.gyb
|
||||
TaskGroup+addTask.swift.gyb
|
||||
Task+immediate.swift.gyb
|
||||
)
|
||||
|
||||
add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
|
||||
${SWIFT_RUNTIME_CONCURRENCY_C_SOURCES}
|
||||
${SWIFT_RUNTIME_CONCURRENCY_EXECUTOR_SOURCES}
|
||||
@@ -214,8 +219,7 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
|
||||
${SWIFT_RUNTIME_CONCURRENCY_NONEMBEDDED_SWIFT_SOURCES}
|
||||
|
||||
GYB_SOURCES
|
||||
TaskGroup+addTask.swift.gyb
|
||||
Task+immediate.swift.gyb
|
||||
${SWIFT_CONCURRENCY_GYB_SOURCES}
|
||||
|
||||
SWIFT_MODULE_DEPENDS_ANDROID Android
|
||||
SWIFT_MODULE_DEPENDS_LINUX Glibc
|
||||
@@ -303,8 +307,10 @@ if(SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB AND SWIFT_SHOULD_BUILD_EMBEDDED_CONCURRENC
|
||||
endif()
|
||||
|
||||
set(SWIFT_SDK_embedded_THREADING_PACKAGE none)
|
||||
set(SWIFT_SDK_embedded_ARCH_${arch}_MODULE "${mod}")
|
||||
set(SWIFT_SDK_embedded_ARCH_${mod}_MODULE "${mod}")
|
||||
set(SWIFT_SDK_embedded_LIB_SUBDIR "embedded")
|
||||
set(SWIFT_SDK_embedded_ARCH_${arch}_TRIPLE "${triple}")
|
||||
set(SWIFT_SDK_embedded_ARCH_${mod}_TRIPLE "${triple}")
|
||||
|
||||
# lib/swift/embedded/_Concurrency.swiftmodule
|
||||
@@ -319,6 +325,9 @@ if(SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB AND SWIFT_SHOULD_BUILD_EMBEDDED_CONCURRENC
|
||||
${SWIFT_RUNTIME_CONCURRENCY_SWIFT_SOURCES}
|
||||
${SWIFT_RUNTIME_CONCURRENCY_EMBEDDED_SWIFT_SOURCES}
|
||||
|
||||
GYB_SOURCES
|
||||
${SWIFT_CONCURRENCY_GYB_SOURCES}
|
||||
|
||||
SWIFT_COMPILE_FLAGS
|
||||
${extra_swift_compile_flags} -enable-experimental-feature Embedded
|
||||
-parse-stdlib -DSWIFT_CONCURRENCY_EMBEDDED
|
||||
@@ -328,7 +337,8 @@ if(SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB AND SWIFT_SHOULD_BUILD_EMBEDDED_CONCURRENC
|
||||
${extra_c_compile_flags} ${SWIFT_RUNTIME_CONCURRENCY_C_FLAGS} -DSWIFT_CONCURRENCY_EMBEDDED=1 -DSWIFT_RUNTIME_EMBEDDED=1
|
||||
MODULE_DIR "${CMAKE_BINARY_DIR}/lib/swift/embedded"
|
||||
SDK "embedded"
|
||||
ARCHITECTURE "${mod}"
|
||||
ARCHITECTURE "${arch}"
|
||||
ARCHITECTURE_SUBDIR_NAME "${mod}"
|
||||
DEPENDS embedded-stdlib-${mod}
|
||||
INSTALL_IN_COMPONENT stdlib
|
||||
)
|
||||
|
||||
@@ -87,175 +87,6 @@ extension Task where Success == Never, Failure == Never {
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension Task where Failure == Error {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public static func runDetached(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: __owned @Sendable @escaping () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, deprecated, message: "`Task.runDetached` was replaced by `Task.detached` and will be removed shortly.")
|
||||
public static func runDetached(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: __owned @Sendable @escaping () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
detached(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
@_alwaysEmitIntoClient
|
||||
public func detach<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: __owned @Sendable @escaping () async -> T
|
||||
) -> Task<T, Never> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, deprecated, message: "`detach` was replaced by `Task.detached` and will be removed shortly.")
|
||||
@_alwaysEmitIntoClient
|
||||
public func detach<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: __owned @Sendable @escaping () async -> T
|
||||
) -> Task<T, Never> {
|
||||
Task.detached(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
@_alwaysEmitIntoClient
|
||||
public func detach<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: __owned @Sendable @escaping () async throws -> T
|
||||
) -> Task<T, Error> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, deprecated, message: "`detach` was replaced by `Task.detached` and will be removed shortly.")
|
||||
@_alwaysEmitIntoClient
|
||||
public func detach<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: __owned @Sendable @escaping () async throws -> T
|
||||
) -> Task<T, Error> {
|
||||
Task.detached(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
@_alwaysEmitIntoClient
|
||||
public func asyncDetached<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_implicitSelfCapture operation: __owned @Sendable @escaping () async -> T
|
||||
) -> Task<T, Never> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, deprecated, message: "`asyncDetached` was replaced by `Task.detached` and will be removed shortly.")
|
||||
@_alwaysEmitIntoClient
|
||||
public func asyncDetached<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_implicitSelfCapture operation: __owned @Sendable @escaping () async -> T
|
||||
) -> Task<T, Never> {
|
||||
return Task.detached(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
@_alwaysEmitIntoClient
|
||||
public func asyncDetached<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_implicitSelfCapture operation: __owned @Sendable @escaping () async throws -> T
|
||||
) -> Task<T, Error> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@discardableResult
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, deprecated, message: "`asyncDetached` was replaced by `Task.detached` and will be removed shortly.")
|
||||
@_alwaysEmitIntoClient
|
||||
public func asyncDetached<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_implicitSelfCapture operation: __owned @Sendable @escaping () async throws -> T
|
||||
) -> Task<T, Error> {
|
||||
return Task.detached(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public func async<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async -> T
|
||||
) -> Task<T, Never> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, deprecated, message: "`async` was replaced by `Task.init` and will be removed shortly.")
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public func async<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async -> T
|
||||
) -> Task<T, Never> {
|
||||
.init(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public func async<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async throws -> T
|
||||
) -> Task<T, Error> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@available(*, deprecated, message: "`async` was replaced by `Task.init` and will be removed shortly.")
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public func async<T>(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async throws -> T
|
||||
) -> Task<T, Error> {
|
||||
.init(priority: priority, operation: operation)
|
||||
}
|
||||
#endif
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension Task where Success == Never, Failure == Never {
|
||||
@available(*, deprecated, message: "`Task.Group` was replaced by `ThrowingTaskGroup` and `TaskGroup` and will be removed shortly.")
|
||||
|
||||
@@ -187,263 +187,6 @@ public func _unsafeInheritExecutor_withTaskExecutorPreference<T: Sendable>(
|
||||
return try await operation()
|
||||
}
|
||||
|
||||
/// Task with specified executor -----------------------------------------------
|
||||
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
@_unavailableInEmbedded
|
||||
extension Task where Failure == Never {
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task on behalf of the current actor.
|
||||
///
|
||||
/// This overload allows specifying a preferred ``TaskExecutor`` on which
|
||||
/// the `operation`, as well as all child tasks created from this task will be
|
||||
/// executing whenever possible. Refer to ``TaskExecutor`` for a detailed discussion
|
||||
/// of the effect of task executors on execution semantics of asynchronous code.
|
||||
///
|
||||
/// Use this function when creating asynchronous work
|
||||
/// that operates on behalf of the synchronous function that calls it.
|
||||
/// Like `Task.detached(priority:operation:)`,
|
||||
/// this function creates a separate, top-level task.
|
||||
/// Unlike `Task.detached(priority:operation:)`,
|
||||
/// the task created by `Task.init(priority:operation:)`
|
||||
/// inherits the priority and actor context of the caller,
|
||||
/// so the operation is treated more like an asynchronous extension
|
||||
/// to the synchronous operation.
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - taskExecutor: the preferred task executor for this task,
|
||||
/// and any child tasks created by it. Explicitly passing `nil` is
|
||||
/// interpreted as "no preference".
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
/// - SeeAlso: ``withTaskExecutorPreference(_:operation:)``
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public init(
|
||||
executorPreference taskExecutor: consuming (any TaskExecutor)?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping () async -> Success
|
||||
) {
|
||||
guard let taskExecutor else {
|
||||
self = Self.init(priority: priority, operation: operation)
|
||||
return
|
||||
}
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
let (task, _) = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
operation: operation)
|
||||
#else
|
||||
let executorBuiltin: Builtin.Executor =
|
||||
taskExecutor.asUnownedTaskExecutor().executor
|
||||
let (task, _) = Builtin.createAsyncTaskWithExecutor(
|
||||
flags, executorBuiltin, operation)
|
||||
#endif
|
||||
self._task = task
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
@_unavailableInEmbedded
|
||||
extension Task where Failure == Error {
|
||||
/// Runs the given throwing operation asynchronously
|
||||
/// as part of a new top-level task on behalf of the current actor.
|
||||
///
|
||||
/// Use this function when creating asynchronous work
|
||||
/// that operates on behalf of the synchronous function that calls it.
|
||||
/// Like `Task.detached(priority:operation:)`,
|
||||
/// this function creates a separate, top-level task.
|
||||
/// Unlike `detach(priority:operation:)`,
|
||||
/// the task created by `Task.init(priority:operation:)`
|
||||
/// inherits the priority and actor context of the caller,
|
||||
/// so the operation is treated more like an asynchronous extension
|
||||
/// to the synchronous operation.
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - taskExecutor: the preferred task executor for this task,
|
||||
/// and any child tasks created by it. Explicitly passing `nil` is
|
||||
/// interpreted as "no preference".
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
/// - SeeAlso: ``withTaskExecutorPreference(_:operation:)``
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public init(
|
||||
executorPreference taskExecutor: consuming (any TaskExecutor)?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping () async throws -> Success
|
||||
) {
|
||||
guard let taskExecutor else {
|
||||
self = Self.init(priority: priority, operation: operation)
|
||||
return
|
||||
}
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
let (task, _) = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
operation: operation)
|
||||
#else
|
||||
let executorBuiltin: Builtin.Executor =
|
||||
taskExecutor.asUnownedTaskExecutor().executor
|
||||
let (task, _) = Builtin.createAsyncTaskWithExecutor(
|
||||
flags, executorBuiltin, operation)
|
||||
#endif
|
||||
self._task = task
|
||||
}
|
||||
}
|
||||
|
||||
// ==== Detached tasks ---------------------------------------------------------
|
||||
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
@_unavailableInEmbedded
|
||||
extension Task where Failure == Never {
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task.
|
||||
///
|
||||
/// Don't use a detached task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
///
|
||||
/// You need to keep a reference to the detached task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - taskExecutor: the preferred task executor for this task,
|
||||
/// and any child tasks created by it. Explicitly passing `nil` is
|
||||
/// interpreted as "no preference".
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
/// - Returns: A reference to the newly created task.
|
||||
/// - SeeAlso: ``withTaskExecutorPreference(_:operation:)``
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public static func detached(
|
||||
executorPreference taskExecutor: (any TaskExecutor)?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping () async -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
guard let taskExecutor else {
|
||||
return Self.detached(priority: priority, operation: operation)
|
||||
}
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: false,
|
||||
inheritContext: false, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
let (task, _) = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
operation: operation)
|
||||
#else
|
||||
let executorBuiltin: Builtin.Executor =
|
||||
taskExecutor.asUnownedTaskExecutor().executor
|
||||
let (task, _) = Builtin.createAsyncTaskWithExecutor(
|
||||
flags, executorBuiltin, operation)
|
||||
#endif
|
||||
return Task(task)
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
@_unavailableInEmbedded
|
||||
extension Task where Failure == Error {
|
||||
/// Runs the given throwing operation asynchronously
|
||||
/// as part of a new top-level task.
|
||||
///
|
||||
/// If the operation throws an error, this method propagates that error.
|
||||
///
|
||||
/// Don't use a detached task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
///
|
||||
/// You need to keep a reference to the detached task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - taskExecutor: the preferred task executor for this task,
|
||||
/// and any child tasks created by it. Explicitly passing `nil` is
|
||||
/// interpreted as "no preference".
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
/// - Returns: A reference to the newly created task.
|
||||
/// - SeeAlso: ``withTaskExecutorPreference(_:operation:)``
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public static func detached(
|
||||
executorPreference taskExecutor: (any TaskExecutor)?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
guard let taskExecutor else {
|
||||
return Self.detached(priority: priority, operation: operation)
|
||||
}
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: false,
|
||||
inheritContext: false, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
let (task, _) = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
operation: operation)
|
||||
#else
|
||||
let executorBuiltin: Builtin.Executor =
|
||||
taskExecutor.asUnownedTaskExecutor().executor
|
||||
let (task, _) = Builtin.createAsyncTaskWithExecutor(
|
||||
flags, executorBuiltin, operation)
|
||||
#endif
|
||||
return Task(task)
|
||||
}
|
||||
}
|
||||
|
||||
// ==== Unsafe Current Task ----------------------------------------------------
|
||||
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
@_unavailableInEmbedded
|
||||
extension UnsafeCurrentTask {
|
||||
|
||||
415
stdlib/public/Concurrency/Task+init.swift.gyb
Normal file
415
stdlib/public/Concurrency/Task+init.swift.gyb
Normal file
@@ -0,0 +1,415 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2020 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Swift
|
||||
|
||||
% for (METHOD_VARIANTS, ALL_AVAILABILITY, PARAMS) in [
|
||||
% # ==== -------------------------------------------------------------------------------------------------------------
|
||||
% # ==== Without task executor, but available ever since 5.1
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'init',
|
||||
% 'init/*throws*/',
|
||||
% ],
|
||||
% [ # ALL_AVAILABILITY
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'name: String? = nil',
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% '@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success',
|
||||
% ]),
|
||||
% # ==== --------------------------------------------------------------------
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'static func detached',
|
||||
% 'static func detached/*throws*/',
|
||||
% ],
|
||||
% [
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'name: String? = nil',
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% 'operation: sending @escaping @isolated(any) () async throws -> Success',
|
||||
% ]),
|
||||
% # ==== -------------------------------------------------------------------------------------------------------------
|
||||
% # ==== With task executor, but available only since 6.0
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'init',
|
||||
% 'init/*throws*/',
|
||||
% ],
|
||||
% [ # ALL_AVAILABILITY
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 6.0, *)',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'name: String? = nil',
|
||||
% 'executorPreference taskExecutor: (any TaskExecutor)?',
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% 'operation: sending @escaping () async throws -> Success',
|
||||
% ]),
|
||||
% # ==== --------------------------------------------------------------------
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'static func detached',
|
||||
% 'static func detached/*throws*/',
|
||||
% ],
|
||||
% [
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 6.0, *)',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'name: String? = nil',
|
||||
% 'executorPreference taskExecutor: (any TaskExecutor)?',
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% 'operation: sending @escaping () async throws -> Success',
|
||||
% ]),
|
||||
% # !!!! -------------------------------------------------------------------------------------------------------------
|
||||
% # !!!! Legacy / Source Compatibility "Shims"
|
||||
% # !!!!
|
||||
% # !!!! These legacy APIs technically did not have @isolated(any) but since they're all emit-into-client,
|
||||
% # !!!! we just allow them to become slightly better here. It makes source generation simpler, and doesn't really hurt.
|
||||
% # !!!! -------------------------------------------------------------------------------------------------------------
|
||||
% # ==== Legacy API: Global 'detach' function
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'func detach<Success>',
|
||||
% 'func detach<Success>/*throws*/',
|
||||
% ],
|
||||
% [ # ALL_AVAILABILITY
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% '@available(*, deprecated, message: "`detach` was replaced by `Task.detached` and will be removed shortly.")',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
|
||||
% ]),
|
||||
% # ==== Legacy API: runDetached
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'static func runDetached',
|
||||
% 'static func runDetached/*throws*/',
|
||||
% ],
|
||||
% [ # ALL_AVAILABILITY
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% '@available(*, deprecated, message: "`Task.runDetached` was replaced by `Task.detached` and will be removed shortly.")',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
|
||||
% ]),
|
||||
% # ==== Legacy API: asyncDetached
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'func asyncDetached<Success>',
|
||||
% 'func asyncDetached<Success>/*throws*/',
|
||||
% ],
|
||||
% [ # ALL_AVAILABILITY
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% '@available(*, deprecated, message: "`asyncDetached` was replaced by `Task.detached` and will be removed shortly.")',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
|
||||
% ]),
|
||||
% # ==== Legacy API: async
|
||||
% ([ # METHOD_VARIANT
|
||||
% 'func async<Success>',
|
||||
% 'func async<Success>/*throws*/',
|
||||
% ],
|
||||
% [ # ALL_AVAILABILITY
|
||||
% '@_alwaysEmitIntoClient',
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% '@available(*, deprecated, message: "`async` was replaced by `Task.init` and will be removed shortly.")',
|
||||
% ],
|
||||
% [ # PARAMS
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
|
||||
% ]),
|
||||
% ]:
|
||||
% for METHOD_VARIANT in METHOD_VARIANTS:
|
||||
|
||||
% IS_TOP_LEVEL_FUNC = (not ('init' in METHOD_VARIANT)) and (not ('static' in METHOD_VARIANT))
|
||||
% IS_INIT = 'init' in METHOD_VARIANT
|
||||
% IS_DETACHED = 'detach' in METHOD_VARIANT.lower()
|
||||
% IS_THROWING = 'throws' in METHOD_VARIANT
|
||||
%
|
||||
% HAS_TASK_PRIORITY = any('priority:' in param for param in PARAMS)
|
||||
% HAS_TASK_NAME = any('name:' in param for param in PARAMS)
|
||||
% HAS_TASK_EXECUTOR = any('taskExecutor:' in param for param in PARAMS)
|
||||
% HAS_ISOLATED_ANY = any('@isolated(any)' in param for param in PARAMS)
|
||||
% IS_DEPRECATED = any('deprecated' in a for a in ALL_AVAILABILITY)
|
||||
%
|
||||
% if IS_THROWING:
|
||||
% FAILURE_TYPE = 'Error'
|
||||
% else:
|
||||
% FAILURE_TYPE = 'Never'
|
||||
% end
|
||||
|
||||
%{
|
||||
|
||||
def adjust_params_for_kind(params):
|
||||
res = []
|
||||
for p in params:
|
||||
np = p
|
||||
if not IS_THROWING:
|
||||
np = np.replace("throws", "")
|
||||
res.append(np)
|
||||
return res
|
||||
|
||||
def adjust_availability(avails):
|
||||
res = []
|
||||
for av in avails:
|
||||
adjusted = av
|
||||
if HAS_TASK_EXECUTOR:
|
||||
adjusted = adjusted.replace("SwiftStdlib 5.1", "SwiftStdlib 6.0")
|
||||
res.append(adjusted)
|
||||
return res
|
||||
|
||||
if IS_INIT:
|
||||
ARROW_RETURN_TYPE = '' # init does not spell out return type
|
||||
else:
|
||||
ARROW_RETURN_TYPE = f'-> Task<Success, {FAILURE_TYPE}>'
|
||||
|
||||
}%
|
||||
|
||||
% # ====================================================================================================================
|
||||
% if not IS_TOP_LEVEL_FUNC:
|
||||
extension Task where Failure == ${FAILURE_TYPE} {
|
||||
% end
|
||||
|
||||
% # --------------------------------------------------------------------------------------------------------------------
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public ${METHOD_VARIANT}(
|
||||
${",\n ".join(adjust_params_for_kind(PARAMS))}
|
||||
) ${ARROW_RETURN_TYPE}{
|
||||
fatalError("Unavailable in task-to-thread concurrency model.")
|
||||
}
|
||||
|
||||
% # --------------------------------------------------------------------------------------------------------------------
|
||||
% if not HAS_TASK_EXECUTOR:
|
||||
#elseif $Embedded
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
${" \n".join(adjust_availability(['@available(SwiftStdlib 5.1, *)']))}
|
||||
public ${METHOD_VARIANT}(
|
||||
${",\n ".join(adjust_params_for_kind(PARAMS))}
|
||||
) ${ARROW_RETURN_TYPE}{
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: false,
|
||||
copyTaskLocals: ${'true' if not IS_DETACHED else 'false /* detached */'},
|
||||
inheritContext: true,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false,
|
||||
isSynchronousStart: false)
|
||||
|
||||
let (task, _) = Builtin.createAsyncTask(flags, operation)
|
||||
|
||||
% if IS_INIT:
|
||||
self._task = task
|
||||
% else:
|
||||
return Task(task)
|
||||
% end
|
||||
}
|
||||
% end # not HAS_TASK_EXECUTOR
|
||||
|
||||
% # --------------------------------------------------------------------------------------------------------------------
|
||||
#else
|
||||
|
||||
% if IS_DEPRECATED:
|
||||
/// Deprecated, available only for source compatibility reasons.
|
||||
% else:
|
||||
% # We skip documentation for the legacy APIs which are just here for source compatibility reasons.
|
||||
% if IS_THROWING:
|
||||
/// Runs the given throwing operation asynchronously
|
||||
% else:
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
% end
|
||||
% if IS_DETACHED:
|
||||
/// as part of a new _unstructured_ _detached_ top-level task.
|
||||
% else:
|
||||
/// as part of a new _unstructured_ top-level task.
|
||||
% end
|
||||
///
|
||||
% if IS_THROWING:
|
||||
/// If the `operation` throws an error, it is caught by the `Task` and will be
|
||||
/// rethrown only when the task's `value` is awaited. Take care to not accidentally
|
||||
/// dismiss errors by not awaiting on the task's resulting value.
|
||||
% end
|
||||
///
|
||||
% if IS_DETACHED:
|
||||
/// Don't use a detached unstructured task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
% end
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
% if HAS_TASK_NAME:
|
||||
/// - name: Human readable name of the task.
|
||||
% end
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
/// - taskExecutor: The task executor that the child task should be started on and keep using.
|
||||
/// Explicitly passing `nil` as the executor preference is equivalent to no preference,
|
||||
/// and effectively means to inherit the outer context's executor preference.
|
||||
/// You can also pass the ``globalConcurrentExecutor`` global executor explicitly.
|
||||
% end
|
||||
/// - priority: The priority of the operation task.
|
||||
% if IS_DETACHED:
|
||||
/// Omit this parameter or pass `nil` to inherit the enclosing context's base priority.
|
||||
% end
|
||||
/// - operation: The operation to perform.
|
||||
///
|
||||
/// - Returns: A reference to the task.
|
||||
% end # IS_DEPRECATED
|
||||
${"\n ".join(adjust_availability(ALL_AVAILABILITY))}
|
||||
@discardableResult
|
||||
public ${METHOD_VARIANT}( // Task ${METHOD_VARIANT}
|
||||
${",\n ".join(adjust_params_for_kind(PARAMS))}
|
||||
) ${ARROW_RETURN_TYPE}{
|
||||
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: false,
|
||||
copyTaskLocals: ${'true' if not IS_DETACHED else 'false'},
|
||||
inheritContext: ${'true' if not IS_DETACHED else 'false'},
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false,
|
||||
isSynchronousStart: false)
|
||||
|
||||
% if HAS_ISOLATED_ANY:
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
% end # HAS_ISOLATED_ANY
|
||||
|
||||
var task: Builtin.NativeObject?
|
||||
% if HAS_TASK_NAME:
|
||||
#if $BuiltinCreateAsyncTaskName
|
||||
if let name {
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
% if HAS_ISOLATED_ANY:
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
% end
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
% end
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
#else // no $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
// legacy branch for the non-consuming task executor
|
||||
let executorBuiltin: Builtin.Executor =
|
||||
taskExecutor.asUnownedTaskExecutor().executor
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
% if HAS_ISOLATED_ANY:
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
% end
|
||||
initialTaskExecutor: executorBuiltin,
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
#endif // $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
% else: # if no TASK_EXECUTOR
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
% if HAS_ISOLATED_ANY:
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
% end
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
% end # if no HAS_TASK_EXECUTOR
|
||||
} // let name
|
||||
#endif // $BuiltinCreateAsyncTaskName
|
||||
% end # HAS_TASK_NAME
|
||||
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
// Task name was not set, or task name createTask is unavailable
|
||||
if task == nil {
|
||||
assert(name == nil)
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
% if HAS_ISOLATED_ANY:
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
% end
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
operation: operation).0
|
||||
#else
|
||||
// legacy branch for the non-consuming task executor
|
||||
let executorBuiltin: Builtin.Executor =
|
||||
taskExecutor.asUnownedTaskExecutor().executor
|
||||
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
% if HAS_ISOLATED_ANY:
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
% end
|
||||
initialTaskExecutor: executorBuiltin,
|
||||
operation: operation).0
|
||||
#endif
|
||||
}
|
||||
% end # HAS_TASK_EXECUTOR
|
||||
|
||||
if task == nil {
|
||||
// either no task name was set, or names are unsupported
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
% if HAS_ISOLATED_ANY:
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
% end
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
% if IS_INIT:
|
||||
self._task = task!
|
||||
% else:
|
||||
return Task(task!)
|
||||
% end
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
% if not IS_TOP_LEVEL_FUNC:
|
||||
} // extension Task ...
|
||||
% end
|
||||
|
||||
% end
|
||||
% end
|
||||
|
||||
// =====================================================================================================================
|
||||
// =====================================================================================================================
|
||||
@@ -580,630 +580,6 @@ func taskCreateFlags(
|
||||
return bits
|
||||
}
|
||||
|
||||
// ==== Task Creation ----------------------------------------------------------
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension Task where Failure == Never {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public init(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async -> Success
|
||||
) {
|
||||
fatalError("Unavailable in task-to-thread concurrency model.")
|
||||
}
|
||||
#else
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task on behalf of the current actor.
|
||||
///
|
||||
/// Use this function when creating asynchronous work
|
||||
/// that operates on behalf of the synchronous function that calls it.
|
||||
/// Like `Task.detached(priority:operation:)`,
|
||||
/// this function creates a separate, top-level task.
|
||||
/// Unlike `Task.detached(priority:operation:)`,
|
||||
/// the task created by `Task.init(priority:operation:)`
|
||||
/// inherits the priority and actor context of the caller,
|
||||
/// so the operation is treated more like an asynchronous extension
|
||||
/// to the synchronous operation.
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public init(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async -> Success
|
||||
) {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
let (task, _) = Builtin.createTask(flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
operation: operation)
|
||||
|
||||
self._task = task
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
extension Task where Failure == Never {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public init(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async -> Success
|
||||
) {
|
||||
fatalError("Unavailable in task-to-thread concurrency model.")
|
||||
}
|
||||
#elseif $Embedded
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
public init(
|
||||
name: String?,
|
||||
// TaskExecutor is unavailable in embedded
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping () async -> Success
|
||||
) {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: false,
|
||||
copyTaskLocals: true,
|
||||
inheritContext: true,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false,
|
||||
isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task.
|
||||
let (task, _) = Builtin.createAsyncTask(flags, operation)
|
||||
|
||||
self._task = task
|
||||
}
|
||||
#else
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task on behalf of the current actor.
|
||||
///
|
||||
/// Use this function when creating asynchronous work
|
||||
/// that operates on behalf of the synchronous function that calls it.
|
||||
/// Like `Task.detached(priority:operation:)`,
|
||||
/// this function creates a separate, top-level task.
|
||||
/// Unlike `Task.detached(priority:operation:)`,
|
||||
/// the task created by `Task.init(priority:operation:)`
|
||||
/// inherits the priority and actor context of the caller,
|
||||
/// so the operation is treated more like an asynchronous extension
|
||||
/// to the synchronous operation.
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - name: The high-level human-readable name given for this task
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
public init(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async -> Success
|
||||
) {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
var task: Builtin.NativeObject?
|
||||
#if $BuiltinCreateAsyncTaskName
|
||||
if let name {
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if task == nil {
|
||||
// either no task name was set, or names are unsupported
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
self._task = task!
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension Task where Failure == Error {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public init(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
/// Runs the given throwing operation asynchronously
|
||||
/// as part of a new top-level task on behalf of the current actor.
|
||||
///
|
||||
/// Use this function when creating asynchronous work
|
||||
/// that operates on behalf of the synchronous function that calls it.
|
||||
/// Like `Task.detached(priority:operation:)`,
|
||||
/// this function creates a separate, top-level task.
|
||||
/// Unlike `detach(priority:operation:)`,
|
||||
/// the task created by `Task.init(priority:operation:)`
|
||||
/// inherits the priority and actor context of the caller,
|
||||
/// so the operation is treated more like an asynchronous extension
|
||||
/// to the synchronous operation.
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public init(
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) {
|
||||
// Set up the task flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task future.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
let (task, _) = Builtin.createTask(flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
operation: operation)
|
||||
|
||||
self._task = task
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
extension Task where Failure == Error {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public init(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) {
|
||||
fatalError("Unavailable in task-to-thread concurrency model.")
|
||||
}
|
||||
#elseif $Embedded
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
public init(
|
||||
name: String?,
|
||||
// TaskExecutor is unavailable in embedded
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping () async throws -> Success
|
||||
) {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task.
|
||||
let (task, _) = Builtin.createAsyncTask(flags, operation)
|
||||
|
||||
self._task = task
|
||||
}
|
||||
#else
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task on behalf of the current actor.
|
||||
///
|
||||
/// Use this function when creating asynchronous work
|
||||
/// that operates on behalf of the synchronous function that calls it.
|
||||
/// Like `Task.detached(priority:operation:)`,
|
||||
/// this function creates a separate, top-level task.
|
||||
/// Unlike `Task.detached(priority:operation:)`,
|
||||
/// the task created by `Task.init(priority:operation:)`
|
||||
/// inherits the priority and actor context of the caller,
|
||||
/// so the operation is treated more like an asynchronous extension
|
||||
/// to the synchronous operation.
|
||||
///
|
||||
/// You need to keep a reference to the task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - name: The high-level human-readable name given for this task
|
||||
/// - priority: The priority of the task.
|
||||
/// Pass `nil` to use the priority from `Task.currentPriority`.
|
||||
/// - operation: The operation to perform.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
public init(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: true,
|
||||
inheritContext: true, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
var task: Builtin.NativeObject?
|
||||
#if $BuiltinCreateAsyncTaskName
|
||||
if let name {
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if task == nil {
|
||||
// either no task name was set, or names are unsupported
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
self._task = task!
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ==== Detached Tasks ---------------------------------------------------------
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension Task where Failure == Never {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public static func detached(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task.
|
||||
///
|
||||
/// Don't use a detached task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
///
|
||||
/// You need to keep a reference to the detached task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - priority: The priority of the task.
|
||||
/// - operation: The operation to perform.
|
||||
///
|
||||
/// - Returns: A reference to the task.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public static func detached(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: false,
|
||||
inheritContext: false, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task future.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
let (task, _) = Builtin.createTask(flags: flags,
|
||||
initialSerialExecutor:
|
||||
builtinSerialExecutor,
|
||||
operation: operation)
|
||||
|
||||
return Task(task)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
extension Task where Failure == Never {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public static func detached(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
/// Runs the given nonthrowing operation asynchronously
|
||||
/// as part of a new top-level task.
|
||||
///
|
||||
/// Don't use a detached task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
///
|
||||
/// You need to keep a reference to the detached task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - name: Human readable name of the task.
|
||||
/// - priority: The priority of the task.
|
||||
/// - operation: The operation to perform.
|
||||
///
|
||||
/// - Returns: A reference to the task.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public static func detached(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: false,
|
||||
inheritContext: false, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
var task: Builtin.NativeObject?
|
||||
#if $BuiltinCreateAsyncTaskName
|
||||
if let name {
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if task == nil {
|
||||
// either no task name was set, or names are unsupported
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
return Task(task!)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension Task where Failure == Error {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public static func detached(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
/// Runs the given throwing operation asynchronously
|
||||
/// as part of a new top-level task.
|
||||
///
|
||||
/// If the operation throws an error, this method propagates that error.
|
||||
///
|
||||
/// Don't use a detached task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
///
|
||||
/// You need to keep a reference to the detached task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - priority: The priority of the task.
|
||||
/// - operation: The operation to perform.
|
||||
///
|
||||
/// - Returns: A reference to the task.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public static func detached(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: false,
|
||||
inheritContext: false, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task future.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
let (task, _) = Builtin.createTask(flags: flags,
|
||||
initialSerialExecutor:
|
||||
builtinSerialExecutor,
|
||||
operation: operation)
|
||||
|
||||
return Task(task)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
extension Task where Failure == Error {
|
||||
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
|
||||
public static func detached(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
fatalError("Unavailable in task-to-thread concurrency model")
|
||||
}
|
||||
#else
|
||||
/// Runs the given throwing operation asynchronously
|
||||
/// as part of a new top-level task.
|
||||
///
|
||||
/// If the operation throws an error, this method propagates that error.
|
||||
///
|
||||
/// Don't use a detached task if it's possible
|
||||
/// to model the operation using structured concurrency features like child tasks.
|
||||
/// Child tasks inherit the parent task's priority and task-local storage,
|
||||
/// and canceling a parent task automatically cancels all of its child tasks.
|
||||
/// You need to handle these considerations manually with a detached task.
|
||||
///
|
||||
/// You need to keep a reference to the detached task
|
||||
/// if you want to cancel it by calling the `Task.cancel()` method.
|
||||
/// Discarding your reference to a detached task
|
||||
/// doesn't implicitly cancel that task,
|
||||
/// it only makes it impossible for you to explicitly cancel the task.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - priority: The priority of the task.
|
||||
/// - operation: The operation to perform.
|
||||
///
|
||||
/// - Returns: A reference to the task.
|
||||
@discardableResult
|
||||
@_alwaysEmitIntoClient
|
||||
public static func detached(
|
||||
name: String?,
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> Success
|
||||
) -> Task<Success, Failure> {
|
||||
// Set up the job flags for a new task.
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority, isChildTask: false, copyTaskLocals: false,
|
||||
inheritContext: false, enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: false, isSynchronousStart: false)
|
||||
|
||||
// Create the asynchronous task future.
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
var task: Builtin.NativeObject?
|
||||
#if $BuiltinCreateAsyncTaskName
|
||||
if let name {
|
||||
task =
|
||||
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
|
||||
Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if task == nil {
|
||||
// either no task name was set, or names are unsupported
|
||||
task = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
return Task(task!)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ==== Task Name --------------------------------------------------------------
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
@@ -1224,6 +600,13 @@ extension Task where Success == Never, Failure == Never {
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// ### Task name availability
|
||||
/// The task name is only available when running with a recent runtime (Swift 6.2+).
|
||||
///
|
||||
/// ``Task`` initializers which may accept a task name are more available than this property,
|
||||
/// for convenience purposes, in order to not have to set task names conditionally
|
||||
/// however their effect is runtime dependent, and is reflected in the availability of this property.
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
public static var name: String? {
|
||||
return _getCurrentTaskNameString()
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Swift
|
||||
|
||||
// FIXME: This is a workaround for trouble including gyb-generated sources
|
||||
|
||||
#if SWIFT_CONCURRENCY_EMBEDDED
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension TaskGroup {
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTask(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> ChildTaskResult
|
||||
) {
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: true,
|
||||
isDiscardingTask: false,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTaskUnlessCancelled(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> ChildTaskResult
|
||||
) -> Bool {
|
||||
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
|
||||
|
||||
guard canAdd else {
|
||||
return false
|
||||
}
|
||||
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: true,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
extension ThrowingTaskGroup {
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTask(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> ChildTaskResult
|
||||
) {
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: true,
|
||||
isDiscardingTask: false,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTaskUnlessCancelled(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> ChildTaskResult
|
||||
) -> Bool {
|
||||
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
|
||||
|
||||
guard canAdd else {
|
||||
return false
|
||||
}
|
||||
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: true,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
extension DiscardingTaskGroup {
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTask(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> Void
|
||||
) {
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: true,
|
||||
isDiscardingTask: true,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTaskUnlessCancelled(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async -> Void
|
||||
) -> Bool {
|
||||
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
|
||||
|
||||
guard canAdd else {
|
||||
return false
|
||||
}
|
||||
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: true,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
extension ThrowingDiscardingTaskGroup {
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTask(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> Void
|
||||
) {
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: true,
|
||||
isDiscardingTask: true,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public mutating func addTaskUnlessCancelled(
|
||||
priority: TaskPriority? = nil,
|
||||
operation: sending @escaping @isolated(any) () async throws -> Void
|
||||
) -> Bool {
|
||||
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
|
||||
|
||||
guard canAdd else {
|
||||
return false
|
||||
}
|
||||
|
||||
let flags = taskCreateFlags(
|
||||
priority: priority,
|
||||
isChildTask: true,
|
||||
copyTaskLocals: false,
|
||||
inheritContext: false,
|
||||
enqueueJob: true,
|
||||
addPendingGroupTaskUnconditionally: false,
|
||||
isDiscardingTask: true,
|
||||
isSynchronousStart: false
|
||||
)
|
||||
|
||||
let builtinSerialExecutor =
|
||||
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
|
||||
|
||||
_ = Builtin.createTask(
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
operation: operation).0
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -31,7 +31,7 @@ import Swift
|
||||
% 'ThrowingDiscardingTaskGroup'
|
||||
% ],
|
||||
% [
|
||||
% '@available(SwiftStdlib 6.2, *)',
|
||||
% '@available(SwiftStdlib 6.0, *)', # because task executor
|
||||
% '@_unavailableInEmbedded', # since TaskExecutor is not available on embedded
|
||||
% ],
|
||||
% ['addTask', 'addTaskUnlessCancelled'],
|
||||
@@ -43,6 +43,42 @@ import Swift
|
||||
% 'operation: sending @escaping @isolated(any) () async throws -> ChildTaskResult'
|
||||
% ],
|
||||
% ),
|
||||
% (
|
||||
% '', # no #if condition
|
||||
% [
|
||||
% 'TaskGroup',
|
||||
% 'ThrowingTaskGroup',
|
||||
% ],
|
||||
% [
|
||||
% '@available(SwiftStdlib 5.1, *)',
|
||||
% ],
|
||||
% ['addTask', 'addTaskUnlessCancelled'],
|
||||
% [
|
||||
% 'name: String?',
|
||||
% # without task executor
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% # throws and ChildTaskResult will be adjusted per task group type
|
||||
% 'operation: sending @escaping @isolated(any) () async throws -> ChildTaskResult'
|
||||
% ],
|
||||
% ),
|
||||
% (
|
||||
% '', # no #if condition
|
||||
% [
|
||||
% 'DiscardingTaskGroup',
|
||||
% 'ThrowingDiscardingTaskGroup'
|
||||
% ],
|
||||
% [
|
||||
% '@available(SwiftStdlib 5.9, *)', # because Discarding task groups
|
||||
% ],
|
||||
% ['addTask', 'addTaskUnlessCancelled'],
|
||||
% [
|
||||
% 'name: String?',
|
||||
% # without task executor
|
||||
% 'priority: TaskPriority? = nil',
|
||||
% # throws and ChildTaskResult will be adjusted per task group type
|
||||
% 'operation: sending @escaping @isolated(any) () async throws -> ChildTaskResult'
|
||||
% ],
|
||||
% ),
|
||||
% # -----------------------------------------------------------------------
|
||||
% # === Added TaskExecutor
|
||||
% (
|
||||
@@ -170,7 +206,9 @@ import Swift
|
||||
#if ${IFDEF}
|
||||
% end
|
||||
|
||||
% if IS_DISCARDING:
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
% elif IS_DISCARDING:
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
% else:
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
@@ -267,7 +305,9 @@ extension ${TYPE} {
|
||||
flags: flags,
|
||||
initialSerialExecutor: builtinSerialExecutor,
|
||||
taskGroup: _group,
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
initialTaskExecutorConsuming: taskExecutor,
|
||||
% end
|
||||
taskName: nameBytes.baseAddress!._rawValue,
|
||||
operation: operation).0
|
||||
}
|
||||
@@ -275,8 +315,8 @@ extension ${TYPE} {
|
||||
#endif // $BuiltinCreateAsyncTaskName
|
||||
% end # HAS_TASK_NAME
|
||||
|
||||
// Task name was not set, or task name createTask is unavailable
|
||||
% if HAS_TASK_EXECUTOR:
|
||||
// Task name was not set, or task name createTask is unavailable
|
||||
if task == nil, let taskExecutor {
|
||||
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
|
||||
task = ${TASK_CREATE_FN}(
|
||||
|
||||
73
test/Concurrency/task_naming_availability.swift
Normal file
73
test/Concurrency/task_naming_availability.swift
Normal file
@@ -0,0 +1,73 @@
|
||||
// RUN: %target-swift-frontend -emit-sil -verify -o /dev/null -verify %s
|
||||
|
||||
struct Boom: Error {}
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
func testName() {
|
||||
_ = Task.name
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.0, *)
|
||||
func taskExecutor() async {
|
||||
Task(name: "name", executorPreference: nil) { }
|
||||
Task(name: "name", executorPreference: nil) { throw Boom() }
|
||||
|
||||
Task.detached(name: "name", executorPreference: nil) { throw Boom() }
|
||||
|
||||
await withTaskGroup(of: Void.self) { group in
|
||||
group.addTask(name: "name", executorPreference: nil) {
|
||||
()
|
||||
}
|
||||
}
|
||||
await withThrowingTaskGroup(of: Void.self) { group in
|
||||
group.addTask(name: "name", executorPreference: nil) {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
await withDiscardingTaskGroup { group in
|
||||
group.addTask(name: "name", executorPreference: nil) {
|
||||
()
|
||||
}
|
||||
}
|
||||
try! await withThrowingDiscardingTaskGroup { group in
|
||||
group.addTask(name: "name", executorPreference: nil) {
|
||||
()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
func backDeployedNames() async {
|
||||
Task(name: "name") { }
|
||||
Task(name: "name") { throw Boom() }
|
||||
|
||||
Task.detached(name: "name") { }
|
||||
Task.detached(name: "name") { throw Boom() }
|
||||
|
||||
await withTaskGroup(of: Void.self) { group in
|
||||
group.addTask(name: "name") {
|
||||
()
|
||||
}
|
||||
}
|
||||
await withThrowingTaskGroup(of: Void.self) { group in
|
||||
group.addTask(name: "name") {
|
||||
()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 5.9, *)
|
||||
func backDeployedDiscarding() async {
|
||||
await withDiscardingTaskGroup { group in
|
||||
group.addTask(name: "name") {
|
||||
()
|
||||
}
|
||||
}
|
||||
try! await withThrowingDiscardingTaskGroup { group in
|
||||
group.addTask(name: "name") {
|
||||
()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1767,7 +1767,7 @@ extension MyActor {
|
||||
_ = sc
|
||||
|
||||
Task { // expected-tns-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
|
||||
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to initializer 'init(priority:operation:)' risks causing races in between local and caller code}}
|
||||
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to initializer 'init(name:priority:operation:)' risks causing races in between local and caller code}}
|
||||
_ = sc
|
||||
}
|
||||
|
||||
@@ -1975,7 +1975,7 @@ func mutableLocalCaptureDataRace() async {
|
||||
_ = x
|
||||
|
||||
Task.detached { x = 1 } // expected-tns-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
|
||||
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to static method 'detached(priority:operation:)' risks causing races in between local and caller code}}
|
||||
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to static method 'detached(name:priority:operation:)' risks causing races in between local and caller code}}
|
||||
|
||||
x = 2 // expected-tns-note {{access can happen concurrently}}
|
||||
}
|
||||
@@ -1985,7 +1985,7 @@ func mutableLocalCaptureDataRace2() async {
|
||||
x = 0
|
||||
|
||||
Task.detached { x = 1 } // expected-tns-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
|
||||
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to static method 'detached(priority:operation:)' risks causing races in between local and caller code}}
|
||||
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to static method 'detached(name:priority:operation:)' risks causing races in between local and caller code}}
|
||||
|
||||
print(x) // expected-tns-note {{access can happen concurrently}}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ extension MyActor {
|
||||
_ = sc
|
||||
|
||||
Task { // expected-error {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
|
||||
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to initializer 'init(priority:operation:)' risks causing races in between local and caller code}}
|
||||
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to initializer 'init(name:priority:operation:)' risks causing races in between local and caller code}}
|
||||
_ = sc
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +167,9 @@ class WasmStdlib(cmake_product.CMakeProduct):
|
||||
self.cmake_options.define('SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB:BOOL', 'TRUE')
|
||||
self.cmake_options.define(
|
||||
'SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB_CROSS_COMPILING', 'TRUE')
|
||||
self.cmake_options.define(
|
||||
'SWIFT_SDK_embedded_ARCH_wasm32_PATH:PATH',
|
||||
self._wasi_sysroot_path("wasm32-wasi"))
|
||||
self.cmake_options.define(
|
||||
'SWIFT_SDK_embedded_ARCH_wasm32-unknown-wasip1_PATH:PATH',
|
||||
self._wasi_sysroot_path("wasm32-wasi"))
|
||||
|
||||
Reference in New Issue
Block a user