@@ -122,16 +122,6 @@ extension Task.Priority {
122
122
123
123
return self
124
124
}
125
-
126
- /// Adjust the given priority (when it is unspecified) by the current
127
- /// priority Return the current priority that,
128
- var _inheritingContextualPriority : Task . Priority {
129
- if self != . unspecified {
130
- return self
131
- }
132
-
133
- return Task . currentPriority. _downgradeUserInteractive
134
- }
135
125
}
136
126
137
127
// ==== Task Handle ------------------------------------------------------------
@@ -338,6 +328,22 @@ extension Task {
338
328
}
339
329
}
340
330
331
+ /// Whether this is a task created by the 'async' operation, which
332
+ /// conceptually continues the work of the synchronous code that invokes
333
+ /// it.
334
+ var isContinuingAsyncTask : Bool {
335
+ get {
336
+ ( bits & ( 1 << 27 ) ) != 0
337
+ }
338
+
339
+ set {
340
+ if newValue {
341
+ bits = bits | 1 << 27
342
+ } else {
343
+ bits = ( bits & ~ ( 1 << 27 ) )
344
+ }
345
+ }
346
+ }
341
347
}
342
348
}
343
349
@@ -483,6 +489,22 @@ public func asyncDetached<T>(
483
489
return detach ( priority: priority, operation: operation)
484
490
}
485
491
492
+ /// ABI stub while we stage in the new signatures
493
+ @available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
494
+ @usableFromInline
495
+ func async (
496
+ priority: Task . Priority ,
497
+ @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> Void
498
+ ) {
499
+ let adjustedPriority : Task . Priority ?
500
+ if priority == . unspecified {
501
+ adjustedPriority = nil
502
+ } else {
503
+ adjustedPriority = priority
504
+ }
505
+ let _: Task . Handle = async ( priority: adjustedPriority, operation: operation)
506
+ }
507
+
486
508
/// Run given `operation` as asynchronously in its own top-level task.
487
509
///
488
510
/// The `async` function should be used when creating asynchronous work
@@ -494,27 +516,63 @@ public func asyncDetached<T>(
494
516
/// does not return a handle to refer to the task.
495
517
///
496
518
/// - Parameters:
497
- /// - priority: priority of the task. If unspecified, the priority will
498
- /// be inherited from the task that is currently executing
499
- /// or, if there is none, from the platform's understanding of
500
- /// which thread is executing.
519
+ /// - priority: priority of the task. If nil, the priority will come from
520
+ /// Task.currentPriority.
501
521
/// - operation: the operation to execute
502
522
@available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
503
- public func async (
504
- priority: Task . Priority = . unspecified,
505
- @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> Void
506
- ) {
523
+ public func async < T> (
524
+ priority: Task . Priority ? = nil ,
525
+ @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> T
526
+ ) -> Task . Handle < T , Never > {
527
+ // Set up the job flags for a new task.
528
+ var flags = Task . JobFlags ( )
529
+ flags. kind = . task
530
+ flags. priority = priority ?? Task . currentPriority. _downgradeUserInteractive
531
+ flags. isFuture = true
532
+ flags. isContinuingAsyncTask = true
533
+
534
+ // Create the asynchronous task future.
535
+ let ( task, _) = Builtin . createAsyncTaskFuture ( flags. bits, operation)
536
+
537
+ // Enqueue the resulting job.
538
+ _enqueueJobGlobal ( Builtin . convertTaskToJob ( task) )
539
+
540
+ return Task . Handle ( task)
541
+ }
542
+
543
+ /// Run given `operation` as asynchronously in its own top-level task.
544
+ ///
545
+ /// The `async` function should be used when creating asynchronous work
546
+ /// that operates on behalf of the synchronous function that calls it.
547
+ /// Like `detach`, the async function creates a separate, top-level task.
548
+ /// Unlike `detach`, the task creating by `async` inherits the priority and
549
+ /// actor context of the caller, so the `operation` is treated more like an
550
+ /// asynchronous extension to the synchronous operation. Additionally, `async`
551
+ /// does not return a handle to refer to the task.
552
+ ///
553
+ /// - Parameters:
554
+ /// - priority: priority of the task. If nil, the priority will come from
555
+ /// Task.currentPriority.
556
+ /// - operation: the operation to execute
557
+ @available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
558
+ public func async < T> (
559
+ priority: Task . Priority ? = nil ,
560
+ @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async throws -> T
561
+ ) -> Task . Handle < T , Error > {
507
562
// Set up the job flags for a new task.
508
563
var flags = Task . JobFlags ( )
509
564
flags. kind = . task
510
- flags. priority = priority. _inheritingContextualPriority
565
+ flags. priority = priority ?? Task . currentPriority . _downgradeUserInteractive
511
566
flags. isFuture = true
567
+ flags. isContinuingAsyncTask = true
512
568
513
569
// Create the asynchronous task future.
514
570
let ( task, _) = Builtin . createAsyncTaskFuture ( flags. bits, operation)
515
571
516
572
// Enqueue the resulting job.
517
573
_enqueueJobGlobal ( Builtin . convertTaskToJob ( task) )
574
+
575
+ return Task . Handle ( task)
518
576
}
519
577
520
578
// ==== Async Handler ----------------------------------------------------------
0 commit comments