@@ -178,9 +178,14 @@ package func withTimeout<T: Sendable>(
178178 _ duration: Duration ,
179179 _ body: @escaping @Sendable ( ) async throws -> T
180180) async throws -> T {
181+ // Get the priority with which to launch the body task here so that we can pass the same priority as the initial
182+ // priority to `withTaskPriorityChangedHandler`. Otherwise, we can get into a race condition where bodyTask gets
183+ // launched with a low priority, then the priority gets elevated before we call with `withTaskPriorityChangedHandler`,
184+ // we thus don't receive a `taskPriorityChanged` and hence never increase the priority of `bodyTask`.
185+ let priority = Task . currentPriority
181186 var mutableTasks : [ Task < Void , Error > ] = [ ]
182187 let stream = AsyncThrowingStream < T , Error > { continuation in
183- let bodyTask = Task < Void , Error > {
188+ let bodyTask = Task < Void , Error > ( priority : priority ) {
184189 do {
185190 let result = try await body ( )
186191 continuation. yield ( result)
@@ -189,7 +194,7 @@ package func withTimeout<T: Sendable>(
189194 }
190195 }
191196
192- let timeoutTask = Task {
197+ let timeoutTask = Task ( priority : priority ) {
193198 try await Task . sleep ( for: duration)
194199 continuation. yield ( with: . failure( TimeoutError ( ) ) )
195200 bodyTask. cancel ( )
@@ -199,7 +204,7 @@ package func withTimeout<T: Sendable>(
199204
200205 let tasks = mutableTasks
201206
202- return try await withTaskPriorityChangedHandler {
207+ return try await withTaskPriorityChangedHandler ( initialPriority : priority ) {
203208 for try await value in stream {
204209 return value
205210 }
0 commit comments