Skip to content

Commit 71b2131

Browse files
committed
[Concurrency] gyb generate _startSynchronously
1 parent 4fe774f commit 71b2131

File tree

6 files changed

+109
-95
lines changed

6 files changed

+109
-95
lines changed

Runtimes/Core/Concurrency/CMakeLists.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
add_subdirectory(InternalShims)
22

3+
gyb_expand(Task+startSynchronously.swift.gyb Task+startSynchronously.swift)
4+
35
add_library(swift_Concurrency
46
Actor.cpp
57
AsyncLet.cpp
@@ -80,7 +82,9 @@ add_library(swift_Concurrency
8082
TaskGroup+TaskExecutor.swift
8183
TaskLocal.swift
8284
TaskSleep.swift
83-
TaskSleepDuration.swift)
85+
TaskSleepDuration.swift
86+
"${CMAKE_CURRENT_BINARY_DIR}/Task+startSynchronously.swift")
87+
8488
include(${SwiftCore_CONCURRENCY_GLOBAL_EXECUTOR}.cmake)
8589
target_compile_definitions(swift_Concurrency PRIVATE
8690
$<$<COMPILE_LANGUAGE:C,CXX>:-DSWIFT_TARGET_LIBRARY_NAME=swift_Concurrency>

stdlib/public/Concurrency/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
181181
${SWIFT_RUNTIME_CONCURRENCY_EXECUTOR_SOURCES}
182182
${SWIFT_RUNTIME_CONCURRENCY_SWIFT_SOURCES}
183183

184+
GYB_SOURCES
185+
Task+startSynchronously.swift.gyb
186+
184187
SWIFT_MODULE_DEPENDS_ANDROID Android
185188
SWIFT_MODULE_DEPENDS_LINUX Glibc
186189
SWIFT_MODULE_DEPENDS_LINUX_STATIC Musl
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020-2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Swift
14+
@_implementationOnly import SwiftConcurrencyInternalShims
15+
16+
% METHOD_VARIANTS = [
17+
% 'THROWING',
18+
% 'NON_THROWING',
19+
% ]
20+
% OPERATION_PARAM = '@_inheritActorContext @_implicitSelfCapture _ operation: __owned @Sendable @escaping @MainActor () async throws -> Success'
21+
% for METHOD_VARIANT in METHOD_VARIANTS:
22+
23+
% IS_THROWING = METHOD_VARIANT == 'THROWING'
24+
% if IS_THROWING:
25+
% FAILURE_TYPE = 'Error'
26+
% else:
27+
% FAILURE_TYPE = 'Never'
28+
% end
29+
30+
// ==== Task.startSynchronously ------------------------------------------------
31+
32+
@available(SwiftStdlib 6.2, *)
33+
extension Task where Failure == ${FAILURE_TYPE} {
34+
35+
@available(SwiftStdlib 6.2, *)
36+
@discardableResult
37+
public static func _startSynchronously(
38+
name: String? = nil,
39+
priority: TaskPriority? = nil,
40+
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async -> Success
41+
) -> Task<Success, ${FAILURE_TYPE}> {
42+
let flags = taskCreateFlags(
43+
priority: priority,
44+
isChildTask: false,
45+
copyTaskLocals: true,
46+
inheritContext: true,
47+
enqueueJob: false, // don't enqueue, we'll run it manually
48+
addPendingGroupTaskUnconditionally: false,
49+
isDiscardingTask: false,
50+
isSynchronousStart: true
51+
)
52+
53+
let (task, _) = Builtin.createAsyncTask(flags, operation)
54+
_startTaskSynchronously(task)
55+
return Task<Success, ${FAILURE_TYPE}>(task)
56+
}
57+
}
58+
59+
// ==== Legacy SPI -------------------------------------------------------------
60+
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY && !SWIFT_CONCURRENCY_EMBEDDED
61+
@available(SwiftStdlib 5.9, *)
62+
extension Task where Failure == ${FAILURE_TYPE} {
63+
64+
@_spi(MainActorUtilities)
65+
@MainActor
66+
@available(SwiftStdlib 5.9, *)
67+
@discardableResult
68+
public static func startOnMainActor(
69+
priority: TaskPriority? = nil,
70+
${OPERATION_PARAM if IS_THROWING else OPERATION_PARAM.replace("throws", "")}
71+
) -> Task<Success, ${FAILURE_TYPE}> {
72+
let flags = taskCreateFlags(
73+
priority: priority,
74+
isChildTask: false,
75+
copyTaskLocals: true,
76+
inheritContext: true,
77+
enqueueJob: false,
78+
addPendingGroupTaskUnconditionally: false,
79+
isDiscardingTask: false,
80+
isSynchronousStart: false
81+
)
82+
83+
let (task, _) = Builtin.createAsyncTask(flags, operation)
84+
_startTaskOnMainActor(task)
85+
86+
return Task<Success, ${FAILURE_TYPE}>(task)
87+
}
88+
}
89+
#endif
90+
% end
91+
92+
// Internal Runtime Functions --------------------------------------------------
93+
94+
@_silgen_name("swift_task_startOnMainActor")
95+
fileprivate func _startTaskOnMainActor(_ task: Builtin.NativeObject)
96+
97+
@_silgen_name("swift_task_startSynchronously")
98+
fileprivate func _startTaskSynchronously(_ task: Builtin.NativeObject)

stdlib/public/Concurrency/Task.swift

-81
Original file line numberDiff line numberDiff line change
@@ -273,81 +273,6 @@ extension Task: Equatable {
273273
}
274274
}
275275

276-
// ==== Starting tasks synchronously -------------------------------------------
277-
278-
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY && !SWIFT_CONCURRENCY_EMBEDDED
279-
@available(SwiftStdlib 5.9, *)
280-
extension Task where Failure == Error {
281-
@_spi(MainActorUtilities)
282-
@MainActor
283-
@available(SwiftStdlib 5.9, *)
284-
@discardableResult
285-
public static func startOnMainActor(
286-
priority: TaskPriority? = nil,
287-
@_inheritActorContext @_implicitSelfCapture _ operation: __owned @Sendable @escaping @MainActor() async throws -> Success
288-
) -> Task<Success, Error> {
289-
let flags = taskCreateFlags(priority: priority, isChildTask: false,
290-
copyTaskLocals: true, inheritContext: true,
291-
enqueueJob: false,
292-
addPendingGroupTaskUnconditionally: false,
293-
isDiscardingTask: false, isSynchronousStart: false)
294-
let (task, _) = Builtin.createAsyncTask(flags, operation)
295-
_startTaskOnMainActor(task)
296-
return Task<Success, Error>(task)
297-
}
298-
}
299-
#endif
300-
301-
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY && !SWIFT_CONCURRENCY_EMBEDDED
302-
@available(SwiftStdlib 5.9, *)
303-
extension Task where Failure == Never {
304-
@_spi(MainActorUtilities)
305-
@MainActor
306-
@available(SwiftStdlib 5.9, *)
307-
@discardableResult
308-
public static func startOnMainActor(
309-
priority: TaskPriority? = nil,
310-
@_inheritActorContext @_implicitSelfCapture _ operation: __owned @Sendable @escaping @MainActor() async -> Success
311-
) -> Task<Success, Never> {
312-
let flags = taskCreateFlags(priority: priority, isChildTask: false,
313-
copyTaskLocals: true, inheritContext: true,
314-
enqueueJob: false,
315-
addPendingGroupTaskUnconditionally: false,
316-
isDiscardingTask: false, isSynchronousStart: false)
317-
let (task, _) = Builtin.createAsyncTask(flags, operation)
318-
_startTaskOnMainActor(task)
319-
return Task(task)
320-
}
321-
}
322-
#endif
323-
324-
@available(SwiftStdlib 5.9, *)
325-
extension Task where Failure == Never {
326-
@available(SwiftStdlib 5.9, *)
327-
@discardableResult
328-
public static func _startSynchronously(
329-
name: String? = nil,
330-
priority: TaskPriority? = nil,
331-
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async -> Success
332-
) -> Task<Success, Never> {
333-
let flags = taskCreateFlags(
334-
priority: priority,
335-
isChildTask: false,
336-
copyTaskLocals: true,
337-
inheritContext: true,
338-
enqueueJob: false, // don't enqueue, we'll run it manually
339-
addPendingGroupTaskUnconditionally: false,
340-
isDiscardingTask: false,
341-
isSynchronousStart: true
342-
)
343-
344-
let (task, _) = Builtin.createAsyncTask(flags, operation)
345-
_startTaskSynchronously(task)
346-
return Task<Success, Never>(task)
347-
}
348-
}
349-
350-
351276
// ==== Task Priority ----------------------------------------------------------
352277

353278
/// The priority of a task.
@@ -1451,12 +1376,6 @@ extension UnsafeCurrentTask: Equatable {
14511376
@_silgen_name("swift_task_getCurrent")
14521377
public func _getCurrentAsyncTask() -> Builtin.NativeObject?
14531378

1454-
@_silgen_name("swift_task_startOnMainActor")
1455-
fileprivate func _startTaskOnMainActor(_ task: Builtin.NativeObject)
1456-
1457-
@_silgen_name("swift_task_startSynchronously")
1458-
fileprivate func _startTaskSynchronously(_ task: Builtin.NativeObject)
1459-
14601379
@available(SwiftStdlib 5.1, *)
14611380
@_silgen_name("swift_task_getJobFlags")
14621381
func getJobFlags(_ task: Builtin.NativeObject) -> JobFlags

test/Concurrency/Runtime/startSynchronously.swift

+1-13
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@
1313
// UNSUPPORTED: use_os_stdlib
1414
// UNSUPPORTED: freestanding
1515

16-
@_spi(MainActorUtilities) import _Concurrency
17-
#if canImport(Darwin)
16+
import _Concurrency
1817
import Dispatch
19-
#endif
2018

2119
enum CompareHow {
2220
case equal
@@ -95,7 +93,6 @@ func syncOnMyGlobalActor() -> [Task<Void, Never>] {
9593
return [t1, tt]
9694
}
9795

98-
#if canImport(Darwin) // because Dispatch
9996
func syncOnNonTaskThread(synchronousTask behavior: SynchronousTaskBehavior) {
10097
let sem1 = DispatchSemaphore(value: 0)
10198
let sem2 = DispatchSemaphore(value: 0)
@@ -138,7 +135,6 @@ func syncOnNonTaskThread(synchronousTask behavior: SynchronousTaskBehavior) {
138135

139136
sem2.wait()
140137
}
141-
#endif // Darwin
142138

143139
enum SynchronousTaskBehavior {
144140
case suspend
@@ -165,7 +161,6 @@ await Task { @MyGlobalActor in
165161
// resume on some other thread
166162
// CHECK: after sleep, inside startSynchronously
167163

168-
#if canImport(Darwin) // because Dispatch
169164
print("\n\n==== ------------------------------------------------------------------")
170165
var behavior: SynchronousTaskBehavior = .suspend
171166
print("syncOnNonTaskThread(synchronousTask: \(behavior))")
@@ -179,9 +174,7 @@ syncOnNonTaskThread(synchronousTask: behavior)
179174
// CHECK-NEXT: inside startSynchronously, before sleep [thread:[[CALLING_THREAD2]]]
180175
// CHECK-NEXT: after startSynchronously, outside; cancel (wakeup) the synchronous task! [thread:[[CALLING_THREAD2]]]
181176
// CHECK-NEXT: inside startSynchronously, after sleep
182-
#endif
183177

184-
#if canImport(Darwin) // because Dispatch
185178
print("\n\n==== ------------------------------------------------------------------")
186179
behavior = .dontSuspend
187180
print("syncOnNonTaskThread(synchronousTask: \(behavior))")
@@ -193,9 +186,7 @@ syncOnNonTaskThread(synchronousTask: behavior)
193186
// CHECK-NEXT: inside startSynchronously [thread:[[CALLING_THREAD3]]]
194187
// CHECK: inside startSynchronously, done [thread:[[CALLING_THREAD3]]]
195188
// CHECK: after startSynchronously, outside; cancel (wakeup) the synchronous task! [thread:[[CALLING_THREAD3]]]
196-
#endif
197189

198-
#if canImport(Darwin) // because Dispatch
199190
print("\n\n==== ------------------------------------------------------------------")
200191
print("callActorFromStartSynchronousTask()")
201192
callActorFromStartSynchronousTask(recipient: .recipient(Recipient()))
@@ -325,9 +316,7 @@ func callActorFromStartSynchronousTask(recipient rec: TargetActorToCall) {
325316
sem1.wait()
326317
sem2.wait()
327318
}
328-
#endif
329319

330-
#if canImport(Darwin) // because Dispatch
331320
print("\n\n==== ------------------------------------------------------------------")
332321
print("callActorFromStartSynchronousTask() - actor in custom executor with its own queue")
333322
let actorQueue = DispatchSerialQueue(label: "recipient-actor-queue")
@@ -410,4 +399,3 @@ actor RecipientOnQueue {
410399
}.value
411400
}
412401
}
413-
#endif

test/abi/macOS/arm64/concurrency.swift

+2
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,5 @@ Added: _$ss33withTaskPriorityEscalationHandler9operation02onC9Escalated9isolatio
388388
Added: _swift_task_startSynchronously
389389
// static (extension in Swift):Swift.Task< where B == Swift.Never>._startSynchronously(name: Swift.String?, priority: Swift.TaskPriority?, operation: __owned @Sendable () async -> A) -> Swift.Task<A, Swift.Never>
390390
Added: _$sScTss5NeverORs_rlE19_startSynchronously4name8priority9operationScTyxABGSSSg_ScPSgxyYaYbcntFZ
391+
// static (extension in Swift):Swift.Task< where B == Swift.Error>._startSynchronously(name: Swift.String?, priority: Swift.TaskPriority?, operation: __owned @Sendable () async -> A) -> Swift.Task<A, Swift.Error>
392+
Added: _$sScTss5Error_pRs_rlE19_startSynchronously4name8priority9operationScTyxsAA_pGSSSg_ScPSgxyYaYbcntFZ

0 commit comments

Comments
 (0)