@@ -176,9 +176,14 @@ package func withTimeout<T: Sendable>(
176176 _ duration: Duration ,
177177 _ body: @escaping @Sendable ( ) async throws -> T
178178) async throws -> T {
179+ // Get the priority with which to launch the body task here so that we can pass the same priority as the initial
180+ // priority to `withTaskPriorityChangedHandler`. Otherwise, we can get into a race condition where bodyTask gets
181+ // launched with a low priority, then the priority gets elevated before we call with `withTaskPriorityChangedHandler`,
182+ // we thus don't receive a `taskPriorityChanged` and hence never increase the priority of `bodyTask`.
183+ let priority = Task . currentPriority
179184 var mutableTasks : [ Task < Void , Error > ] = [ ]
180185 let stream = AsyncThrowingStream < T , Error > { continuation in
181- let bodyTask = Task < Void , Error > {
186+ let bodyTask = Task < Void , Error > ( priority : priority ) {
182187 do {
183188 let result = try await body ( )
184189 continuation. yield ( result)
@@ -187,7 +192,7 @@ package func withTimeout<T: Sendable>(
187192 }
188193 }
189194
190- let timeoutTask = Task {
195+ let timeoutTask = Task ( priority : priority ) {
191196 try await Task . sleep ( for: duration)
192197 continuation. yield ( with: . failure( TimeoutError ( ) ) )
193198 bodyTask. cancel ( )
@@ -197,7 +202,7 @@ package func withTimeout<T: Sendable>(
197202
198203 let tasks = mutableTasks
199204
200- return try await withTaskPriorityChangedHandler {
205+ return try await withTaskPriorityChangedHandler ( initialPriority : priority ) {
201206 for try await value in stream {
202207 return value
203208 }
0 commit comments