@@ -929,7 +929,7 @@ extension Task {
929929 /// - task: the task which to escalate the priority of
930930 /// - newPriority: the new priority the task should continue executing on
931931 @available ( SwiftStdlib 9999 , * )
932- public static func escalatePriority( _ task: UnsafeCurrentTask , to newPriority: TaskPriority ) {
932+ public static func escalatePriority( _ task: Task , to newPriority: TaskPriority ) {
933933 _taskEscalate ( task. _task, newPriority: newPriority. rawValue)
934934 }
935935
@@ -964,6 +964,56 @@ extension Task {
964964 }
965965}
966966
967+ /// Runs the passed `operation` while registering a task priority escalation handler.
968+ /// The handler will be triggered concurrently to the current task if the current
969+ /// is subject to priority escalation.
970+ ///
971+ /// The handler may perform additional actions upon priority escalation,
972+ /// but cannot influence how the escalation influences the task, i.e. the task's
973+ /// priority will be escalated regardless of actions performed in the handler.
974+ ///
975+ /// If multiple task escalation handlers are nester they will all be triggered.
976+ ///
977+ /// Task escalation propagates through structured concurrency child-tasks.
978+ ///
979+ /// - Parameters:
980+ /// - operation: the operation during which to listen for priority escalation
981+ /// - handler: handler to invoke, concurrently to `operation`,
982+ /// when priority escalation happens
983+ /// - Returns: the value returned by `operation`
984+ /// - Throws: when the `operation` throws an error
985+ @available ( SwiftStdlib 9999 , * )
986+ public func withTaskPriorityEscalationHandler< T, E> (
987+ operation: ( ) async throws ( E) -> T ,
988+ onEscalate handler: @Sendable ( TaskPriority ) -> Void ,
989+ isolation: isolated ( any Actor ) ? = #isolation
990+ ) async throws ( E) -> T {
991+ // NOTE: We have to create the closure beforehand as otherwise it seems
992+ // the task-local allocator may be used and we end up violating stack-discipline
993+ // when releasing the handler closure vs. the record.
994+ let handler0 : ( UInt8 ) -> Void = {
995+ handler ( TaskPriority ( rawValue: $0) )
996+ }
997+ let record = _taskAddEscalationHandler ( handler: handler0)
998+ defer { _taskRemoveEscalationHandler ( record: record) }
999+
1000+ return try await operation ( )
1001+ }
1002+
1003+ @usableFromInline
1004+ @available ( SwiftStdlib 9999 , * )
1005+ @_silgen_name ( " swift_task_addEscalationHandler " )
1006+ func _taskAddEscalationHandler(
1007+ handler: ( UInt8 ) -> Void
1008+ ) -> UnsafeRawPointer /*EscalationNotificationStatusRecord*/
1009+
1010+ @usableFromInline
1011+ @available ( SwiftStdlib 9999 , * )
1012+ @_silgen_name ( " swift_task_removeEscalationHandler " )
1013+ func _taskRemoveEscalationHandler(
1014+ record: UnsafeRawPointer /*EscalationNotificationStatusRecord*/
1015+ )
1016+
9671017// ==== UnsafeCurrentTask ------------------------------------------------------
9681018
9691019/// Calls a closure with an unsafe reference to the current task.
0 commit comments