Skip to content

Commit 1ae758c

Browse files
committed
[Concurrency] TaskGroup with task names
1 parent 0238f06 commit 1ae758c

File tree

3 files changed

+80
-14
lines changed

3 files changed

+80
-14
lines changed

stdlib/public/Concurrency/Task.swift

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ extension Task where Failure == Never {
704704
@available(SwiftStdlib 6.2, *)
705705
public init(
706706
name: String? = nil,
707+
// TaskExecutor is unavailable in embedded
707708
priority: TaskPriority? = nil,
708709
@_inheritActorContext @_implicitSelfCapture operation: sending @escaping () async -> Success
709710
) {
@@ -762,7 +763,8 @@ extension Task where Failure == Never {
762763
// Create the asynchronous task.
763764
let builtinSerialExecutor =
764765
Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
765-
let task: Builtin.NativeObject
766+
767+
var task: Builtin.NativeObject?
766768
#if $BuiltinCreateAsyncTaskName
767769
if var name {
768770
task =
@@ -773,21 +775,17 @@ extension Task where Failure == Never {
773775
taskName: nameBytes.baseAddress?._rawValue,
774776
operation: operation).0
775777
}
776-
} else {
777-
task = Builtin.createTask(
778-
flags: flags,
779-
initialSerialExecutor: builtinSerialExecutor,
780-
operation: operation).0
781778
}
782-
#else
783-
task = Builtin.createTask(
779+
#endif
780+
if task == nil {
781+
// either no task name was set, or names are unsupported
782+
task = Builtin.createTask(
784783
flags: flags,
785-
// unsupported names, so we drop it.
786784
initialSerialExecutor: builtinSerialExecutor,
787785
operation: operation).0
788-
#endif
786+
}
789787

790-
self._task = task
788+
self._task = task!
791789
}
792790
#endif
793791
}

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,12 +362,72 @@ public struct TaskGroup<ChildTaskResult: Sendable> {
362362
// Create the task in this group.
363363
let builtinSerialExecutor =
364364
Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
365+
365366
_ = Builtin.createTask(flags: flags,
366367
initialSerialExecutor: builtinSerialExecutor,
367368
taskGroup: _group,
368369
operation: operation)
369370
}
370371

372+
/// Adds a child task to the group.
373+
///
374+
/// - Parameters:
375+
/// - name: Human readable name of this task.
376+
/// - priority: The priority of the operation task.
377+
/// Omit this parameter or pass `.unspecified`
378+
/// to set the child task's priority to the priority of the group.
379+
/// - operation: The operation to execute as part of the task group.
380+
@_alwaysEmitIntoClient
381+
public mutating func addTask(
382+
name: String? = nil,
383+
priority: TaskPriority? = nil,
384+
operation: sending @escaping @isolated(any) () async -> ChildTaskResult
385+
) {
386+
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
387+
let enqueueJob = false
388+
#else
389+
let enqueueJob = true
390+
#endif
391+
392+
let flags = taskCreateFlags(
393+
priority: priority, isChildTask: true, copyTaskLocals: false,
394+
inheritContext: false, enqueueJob: enqueueJob,
395+
addPendingGroupTaskUnconditionally: true,
396+
isDiscardingTask: false
397+
)
398+
399+
// Create the task in this group.
400+
let builtinSerialExecutor =
401+
Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
402+
403+
var task: Builtin.NativeObject?
404+
#if $BuiltinCreateAsyncTaskName
405+
if var name {
406+
task =
407+
name.withUTF8 { nameBytes in
408+
Builtin.createTask(
409+
flags: flags,
410+
initialSerialExecutor: builtinSerialExecutor,
411+
taskGroup: _group,
412+
taskName: nameBytes.baseAddress?._rawValue,
413+
operation: operation).0
414+
}
415+
}
416+
#endif
417+
418+
if task == nil {
419+
// either no task name was set, or names are unsupported
420+
task = Builtin.createTask(
421+
flags: flags,
422+
// unsupported names, so we drop it.
423+
initialSerialExecutor: builtinSerialExecutor,
424+
operation: operation).0
425+
}
426+
427+
// task was enqueued to the group, no need to store the 'task' ref itself
428+
assert(task != nil, "Expected task to be created!")
429+
}
430+
371431
/// Adds a child task to the group, unless the group has been canceled.
372432
///
373433
/// - Parameters:

test/Concurrency/Runtime/async_task_naming.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@ func test() async {
2222
// return 12
2323
// }.value
2424

25-
// _ = await withTaskGroup(of: Int.self) { g in
26-
// g.addTask(name: "Caplin the TaskGroup Task") {
27-
// // CHECK: Task.name = Caplin the TaskGroup Task
25+
_ = await withTaskGroup(of: Int.self) { g in
26+
g.addTask(name: "Caplin the TaskGroup Task") {
27+
// CHECK: Task.name = Caplin the TaskGroup Task
28+
print("Task.name = \(Task.name ?? "NONE")")
29+
return 12
30+
}
31+
}
32+
33+
// _ = await withThrowingTaskGroup(of: Int.self) { g in
34+
// g.addTask(name: "Caplin the ThrowingTaskGroup Task") {
35+
// // CHECK: Task.name = Caplin the ThrowingTaskGroup Task
2836
// print("Task.name = \(Task.name ?? "NONE")")
2937
// return 12
3038
// }

0 commit comments

Comments
 (0)