@@ -159,16 +159,6 @@ extension Task.Priority {
159
159
160
160
return self
161
161
}
162
-
163
- /// Adjust the given priority (when it is unspecified) by the current
164
- /// priority Return the current priority that,
165
- var _inheritingContextualPriority : Task . Priority {
166
- if self != . unspecified {
167
- return self
168
- }
169
-
170
- return Task . currentPriority. _downgradeUserInteractive
171
- }
172
162
}
173
163
174
164
// ==== Task Handle ------------------------------------------------------------
@@ -389,6 +379,22 @@ extension Task {
389
379
}
390
380
}
391
381
382
+ /// Whether this is a task created by the 'async' operation, which
383
+ /// conceptually continues the work of the synchronous code that invokes
384
+ /// it.
385
+ var isContinuingAsyncTask : Bool {
386
+ get {
387
+ ( bits & ( 1 << 27 ) ) != 0
388
+ }
389
+
390
+ set {
391
+ if newValue {
392
+ bits = bits | 1 << 27
393
+ } else {
394
+ bits = ( bits & ~ ( 1 << 27 ) )
395
+ }
396
+ }
397
+ }
392
398
}
393
399
}
394
400
@@ -534,6 +540,22 @@ public func asyncDetached<T>(
534
540
return detach ( priority: priority, operation: operation)
535
541
}
536
542
543
+ /// ABI stub while we stage in the new signatures
544
+ @available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
545
+ @usableFromInline
546
+ func async (
547
+ priority: Task . Priority ,
548
+ @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> Void
549
+ ) {
550
+ let adjustedPriority : Task . Priority ?
551
+ if priority == . unspecified {
552
+ adjustedPriority = nil
553
+ } else {
554
+ adjustedPriority = priority
555
+ }
556
+ let _: Task . Handle = async ( priority: adjustedPriority, operation: operation)
557
+ }
558
+
537
559
/// Run given `operation` as asynchronously in its own top-level task.
538
560
///
539
561
/// The `async` function should be used when creating asynchronous work
@@ -545,27 +567,63 @@ public func asyncDetached<T>(
545
567
/// does not return a handle to refer to the task.
546
568
///
547
569
/// - Parameters:
548
- /// - priority: priority of the task. If unspecified, the priority will
549
- /// be inherited from the task that is currently executing
550
- /// or, if there is none, from the platform's understanding of
551
- /// which thread is executing.
570
+ /// - priority: priority of the task. If nil, the priority will come from
571
+ /// Task.currentPriority.
552
572
/// - operation: the operation to execute
553
573
@available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
554
- public func async (
555
- priority: Task . Priority = . unspecified,
556
- @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> Void
557
- ) {
574
+ public func async < T> (
575
+ priority: Task . Priority ? = nil ,
576
+ @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> T
577
+ ) -> Task . Handle < T , Never > {
578
+ // Set up the job flags for a new task.
579
+ var flags = Task . JobFlags ( )
580
+ flags. kind = . task
581
+ flags. priority = priority ?? Task . currentPriority. _downgradeUserInteractive
582
+ flags. isFuture = true
583
+ flags. isContinuingAsyncTask = true
584
+
585
+ // Create the asynchronous task future.
586
+ let ( task, _) = Builtin . createAsyncTaskFuture ( flags. bits, operation)
587
+
588
+ // Enqueue the resulting job.
589
+ _enqueueJobGlobal ( Builtin . convertTaskToJob ( task) )
590
+
591
+ return Task . Handle ( task)
592
+ }
593
+
594
+ /// Run given `operation` as asynchronously in its own top-level task.
595
+ ///
596
+ /// The `async` function should be used when creating asynchronous work
597
+ /// that operates on behalf of the synchronous function that calls it.
598
+ /// Like `detach`, the async function creates a separate, top-level task.
599
+ /// Unlike `detach`, the task creating by `async` inherits the priority and
600
+ /// actor context of the caller, so the `operation` is treated more like an
601
+ /// asynchronous extension to the synchronous operation. Additionally, `async`
602
+ /// does not return a handle to refer to the task.
603
+ ///
604
+ /// - Parameters:
605
+ /// - priority: priority of the task. If nil, the priority will come from
606
+ /// Task.currentPriority.
607
+ /// - operation: the operation to execute
608
+ @available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
609
+ public func async < T> (
610
+ priority: Task . Priority ? = nil ,
611
+ @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async throws -> T
612
+ ) -> Task . Handle < T , Error > {
558
613
// Set up the job flags for a new task.
559
614
var flags = Task . JobFlags ( )
560
615
flags. kind = . task
561
- flags. priority = priority. _inheritingContextualPriority
616
+ flags. priority = priority ?? Task . currentPriority . _downgradeUserInteractive
562
617
flags. isFuture = true
618
+ flags. isContinuingAsyncTask = true
563
619
564
620
// Create the asynchronous task future.
565
621
let ( task, _) = Builtin . createAsyncTaskFuture ( flags. bits, operation)
566
622
567
623
// Enqueue the resulting job.
568
624
_enqueueJobGlobal ( Builtin . convertTaskToJob ( task) )
625
+
626
+ return Task . Handle ( task)
569
627
}
570
628
571
629
// ==== Async Handler ----------------------------------------------------------
0 commit comments