Skip to content

Commit c9d86ee

Browse files
committed
[Freestanding] Disable child task priority spec.
Under the task-to-thread model, specifying a priority doesn't make sense. Here, variations of addTask and addTaskUnlessCancelled are introduced which do not take a priority. Additionally, the original functions are made unavailable.
1 parent fa82280 commit c9d86ee

File tree

3 files changed

+375
-0
lines changed

3 files changed

+375
-0
lines changed

stdlib/public/Concurrency/SourceCompatibilityShims.swift

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ extension Task where Failure == Never {
285285
}
286286
}
287287

288+
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
288289
@available(SwiftStdlib 5.1, *)
289290
extension TaskGroup {
290291
@available(*, deprecated, renamed: "addTask(priority:operation:)")
@@ -334,7 +335,94 @@ extension TaskGroup {
334335
addTaskUnlessCancelled(priority: priority, operation: operation)
335336
}
336337
}
338+
#else
339+
@available(SwiftStdlib 5.1, *)
340+
extension TaskGroup {
341+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
342+
public mutating func add(
343+
priority: TaskPriority? = nil,
344+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
345+
) async -> Bool {
346+
fatalError("Unavailable in task-to-thread concurrency model")
347+
}
348+
349+
@available(*, deprecated, renamed: "addTaskUnlessCancelled(operation:)")
350+
@_alwaysEmitIntoClient
351+
public mutating func add(
352+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
353+
) async -> Bool {
354+
return self.addTaskUnlessCancelled {
355+
await operation()
356+
}
357+
}
358+
359+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
360+
public mutating func spawn(
361+
priority: TaskPriority? = nil,
362+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
363+
) {
364+
fatalError("Unavailable in task-to-thread concurrency model")
365+
}
366+
367+
@available(*, deprecated, renamed: "addTask(operation:)")
368+
@_alwaysEmitIntoClient
369+
public mutating func spawn(
370+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
371+
) {
372+
addTask(operation: operation)
373+
}
374+
375+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
376+
public mutating func spawnUnlessCancelled(
377+
priority: TaskPriority? = nil,
378+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
379+
) -> Bool {
380+
fatalError("Unavailable in task-to-thread concurrency model")
381+
}
382+
383+
@available(*, deprecated, renamed: "addTaskUnlessCancelled(operation:)")
384+
@_alwaysEmitIntoClient
385+
public mutating func spawnUnlessCancelled(
386+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
387+
) -> Bool {
388+
addTaskUnlessCancelled(operation: operation)
389+
}
390+
391+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
392+
public mutating func async(
393+
priority: TaskPriority? = nil,
394+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
395+
) {
396+
fatalError("Unavailable in task-to-thread concurrency model")
397+
}
398+
399+
@available(*, deprecated, renamed: "addTask(operation:)")
400+
@_alwaysEmitIntoClient
401+
public mutating func async(
402+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
403+
) {
404+
addTask(operation: operation)
405+
}
406+
407+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
408+
public mutating func asyncUnlessCancelled(
409+
priority: TaskPriority? = nil,
410+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
411+
) -> Bool {
412+
fatalError("Unavailable in task-to-thread concurrency model")
413+
}
414+
415+
@available(*, deprecated, renamed: "addTaskUnlessCancelled(operation:)")
416+
@_alwaysEmitIntoClient
417+
public mutating func asyncUnlessCancelled(
418+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
419+
) -> Bool {
420+
addTaskUnlessCancelled(operation: operation)
421+
}
422+
}
423+
#endif
337424

425+
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
338426
@available(SwiftStdlib 5.1, *)
339427
extension ThrowingTaskGroup {
340428
@available(*, deprecated, renamed: "addTask(priority:operation:)")
@@ -384,6 +472,92 @@ extension ThrowingTaskGroup {
384472
addTaskUnlessCancelled(priority: priority, operation: operation)
385473
}
386474
}
475+
#else
476+
@available(SwiftStdlib 5.1, *)
477+
extension ThrowingTaskGroup {
478+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
479+
public mutating func add(
480+
priority: TaskPriority? = nil,
481+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
482+
) async -> Bool {
483+
fatalError("Unavailable in task-to-thread concurrency model")
484+
}
485+
486+
@available(*, deprecated, renamed: "addTaskUnlessCancelled(operation:)")
487+
@_alwaysEmitIntoClient
488+
public mutating func add(
489+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
490+
) async -> Bool {
491+
return self.addTaskUnlessCancelled {
492+
try await operation()
493+
}
494+
}
495+
496+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
497+
public mutating func spawn(
498+
priority: TaskPriority? = nil,
499+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
500+
) {
501+
fatalError("Unavailable in task-to-thread concurrency model")
502+
}
503+
504+
@available(*, deprecated, renamed: "addTask(operation:)")
505+
@_alwaysEmitIntoClient
506+
public mutating func spawn(
507+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
508+
) {
509+
addTask(operation: operation)
510+
}
511+
512+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
513+
public mutating func spawnUnlessCancelled(
514+
priority: TaskPriority? = nil,
515+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
516+
) -> Bool {
517+
fatalError("Unavailable in task-to-thread concurrency model")
518+
}
519+
520+
@available(*, deprecated, renamed: "addTaskUnlessCancelled(operation:)")
521+
@_alwaysEmitIntoClient
522+
public mutating func spawnUnlessCancelled(
523+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
524+
) -> Bool {
525+
addTaskUnlessCancelled(operation: operation)
526+
}
527+
528+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
529+
public mutating func async(
530+
priority: TaskPriority? = nil,
531+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
532+
) {
533+
fatalError("Unavailable in task-to-thread concurrency model")
534+
}
535+
536+
@available(*, deprecated, renamed: "addTask(operation:)")
537+
@_alwaysEmitIntoClient
538+
public mutating func async(
539+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
540+
) {
541+
addTask(operation: operation)
542+
}
543+
544+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
545+
public mutating func asyncUnlessCancelled(
546+
priority: TaskPriority? = nil,
547+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
548+
) -> Bool {
549+
fatalError("Unavailable in task-to-thread concurrency model")
550+
}
551+
552+
@available(*, deprecated, renamed: "addTaskUnlessCancelled(operation:)")
553+
@_alwaysEmitIntoClient
554+
public mutating func asyncUnlessCancelled(
555+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
556+
) -> Bool {
557+
addTaskUnlessCancelled(operation: operation)
558+
}
559+
}
560+
#endif
387561

388562
@available(SwiftStdlib 5.1, *)
389563
@available(*, deprecated, message: "please use UnsafeContinuation<..., Error>")

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ public struct TaskGroup<ChildTaskResult: Sendable> {
225225
self._group = group
226226
}
227227

228+
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
228229
/// Adds a child task to the group.
229230
///
230231
/// - Parameters:
@@ -302,6 +303,80 @@ public struct TaskGroup<ChildTaskResult: Sendable> {
302303
fatalError("Unsupported Swift compiler")
303304
#endif
304305
}
306+
#else
307+
@available(SwiftStdlib 5.7, *)
308+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
309+
public mutating func addTask(
310+
priority: TaskPriority? = nil,
311+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
312+
) {
313+
fatalError("Unavailable in task-to-thread concurrency model")
314+
}
315+
316+
/// Adds a child task to the group.
317+
///
318+
/// - Parameters:
319+
/// - operation: The operation to execute as part of the task group.
320+
@_alwaysEmitIntoClient
321+
public mutating func addTask(
322+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
323+
) {
324+
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
325+
let flags = taskCreateFlags(
326+
priority: nil, isChildTask: true, copyTaskLocals: false,
327+
inheritContext: false, enqueueJob: true,
328+
addPendingGroupTaskUnconditionally: true
329+
)
330+
331+
// Create the task in this group.
332+
_ = Builtin.createAsyncTaskInGroup(flags, _group, operation)
333+
#else
334+
fatalError("Unsupported Swift compiler")
335+
#endif
336+
}
337+
338+
@available(SwiftStdlib 5.7, *)
339+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
340+
public mutating func addTaskUnlessCancelled(
341+
priority: TaskPriority? = nil,
342+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
343+
) -> Bool {
344+
fatalError("Unavailable in task-to-thread concurrency model")
345+
}
346+
347+
/// Adds a child task to the group, unless the group has been canceled.
348+
///
349+
/// - Parameters:
350+
/// - operation: The operation to execute as part of the task group.
351+
/// - Returns: `true` if the child task was added to the group;
352+
/// otherwise `false`.
353+
@_alwaysEmitIntoClient
354+
public mutating func addTaskUnlessCancelled(
355+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
356+
) -> Bool {
357+
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
358+
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
359+
360+
guard canAdd else {
361+
// the group is cancelled and is not accepting any new work
362+
return false
363+
}
364+
365+
let flags = taskCreateFlags(
366+
priority: nil, isChildTask: true, copyTaskLocals: false,
367+
inheritContext: false, enqueueJob: true,
368+
addPendingGroupTaskUnconditionally: false
369+
)
370+
371+
// Create the task in this group.
372+
_ = Builtin.createAsyncTaskInGroup(flags, _group, operation)
373+
374+
return true
375+
#else
376+
fatalError("Unsupported Swift compiler")
377+
#endif
378+
}
379+
#endif
305380

306381
/// Wait for the next child task to complete,
307382
/// and return the value it returned.
@@ -490,11 +565,13 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
490565
while let _ = try await next() { }
491566
}
492567

568+
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
493569
/// Adds a child task to the group.
494570
///
495571
/// This method doesn't throw an error, even if the child task does.
496572
/// Instead, the corresponding call to `ThrowingTaskGroup.next()` rethrows that error.
497573
///
574+
/// - Parameters:
498575
/// - overridingPriority: The priority of the operation task.
499576
/// Omit this parameter or pass `.unspecified`
500577
/// to set the child task's priority to the priority of the group.
@@ -557,6 +634,86 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
557634
fatalError("Unsupported Swift compiler")
558635
#endif
559636
}
637+
#else
638+
@available(SwiftStdlib 5.7, *)
639+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
640+
public mutating func addTask(
641+
priority: TaskPriority? = nil,
642+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
643+
) {
644+
fatalError("Unavailable in task-to-thread concurrency model")
645+
}
646+
647+
/// Adds a child task to the group.
648+
///
649+
/// This method doesn't throw an error, even if the child task does.
650+
/// Instead, the corresponding call to `ThrowingTaskGroup.next()` rethrows that error.
651+
///
652+
/// - Parameters:
653+
/// - operation: The operation to execute as part of the task group.
654+
@_alwaysEmitIntoClient
655+
public mutating func addTask(
656+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
657+
) {
658+
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
659+
let flags = taskCreateFlags(
660+
priority: nil, isChildTask: true, copyTaskLocals: false,
661+
inheritContext: false, enqueueJob: true,
662+
addPendingGroupTaskUnconditionally: true
663+
)
664+
665+
// Create the task in this group.
666+
_ = Builtin.createAsyncTaskInGroup(flags, _group, operation)
667+
#else
668+
fatalError("Unsupported Swift compiler")
669+
#endif
670+
}
671+
672+
@available(SwiftStdlib 5.7, *)
673+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
674+
public mutating func addTaskUnlessCancelled(
675+
priority: TaskPriority? = nil,
676+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
677+
) -> Bool {
678+
fatalError("Unavailable in task-to-thread concurrency model")
679+
}
680+
681+
/// Adds a child task to the group, unless the group has been canceled.
682+
///
683+
/// This method doesn't throw an error, even if the child task does.
684+
/// Instead, the corresponding call to `ThrowingTaskGroup.next()` rethrows that error.
685+
///
686+
/// - Parameters:
687+
/// - operation: The operation to execute as part of the task group.
688+
/// - Returns: `true` if the child task was added to the group;
689+
/// otherwise `false`.
690+
@_alwaysEmitIntoClient
691+
public mutating func addTaskUnlessCancelled(
692+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
693+
) -> Bool {
694+
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
695+
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
696+
697+
guard canAdd else {
698+
// the group is cancelled and is not accepting any new work
699+
return false
700+
}
701+
702+
let flags = taskCreateFlags(
703+
priority: nil, isChildTask: true, copyTaskLocals: false,
704+
inheritContext: false, enqueueJob: true,
705+
addPendingGroupTaskUnconditionally: false
706+
)
707+
708+
// Create the task in this group.
709+
_ = Builtin.createAsyncTaskInGroup(flags, _group, operation)
710+
711+
return true
712+
#else
713+
fatalError("Unsupported Swift compiler")
714+
#endif
715+
}
716+
#endif
560717

561718
/// Wait for the next child task to complete,
562719
/// and return the value it returned or rethrow the error it threw.

0 commit comments

Comments
 (0)