@@ -222,24 +222,50 @@ public class HTTPClient {
222
222
"""
223
223
)
224
224
}
225
- let errorStorage : NIOLockedValueBox < Error ? > = NIOLockedValueBox ( nil )
226
- let dispatchGroup = DispatchGroup ( )
227
- dispatchGroup. enter ( )
228
- self . shutdown ( requiresCleanClose: requiresCleanClose, queue: DispatchQueue ( label: " async-http-client.shutdown " ) )
229
- { error in
230
- if let error = error {
231
- errorStorage. withLockedValue { errorStorage in
232
- errorStorage = error
225
+
226
+ final class ShutdownError : @unchecked Sendable {
227
+ // @unchecked because error is protected by lock.
228
+
229
+ // Stores whether the shutdown has happened or not.
230
+ private let lock : ConditionLock < Bool >
231
+ private var error : Error ?
232
+
233
+ init ( ) {
234
+ self . error = nil
235
+ self . lock = ConditionLock ( value: false )
236
+ }
237
+
238
+ func didShutdown( _ error: ( any Error ) ? ) {
239
+ self . lock. lock ( whenValue: false )
240
+ defer {
241
+ self . lock. unlock ( withValue: true )
233
242
}
243
+ self . error = error
234
244
}
235
- dispatchGroup. leave ( )
236
- }
237
- dispatchGroup. wait ( )
238
- try errorStorage. withLockedValue { errorStorage in
239
- if let error = errorStorage {
240
- throw error
245
+
246
+ func blockUntilShutdown( ) -> ( any Error ) ? {
247
+ self . lock. lock ( whenValue: true )
248
+ defer {
249
+ self . lock. unlock ( withValue: true )
250
+ }
251
+ return self . error
241
252
}
242
253
}
254
+
255
+ let shutdownError = ShutdownError ( )
256
+
257
+ self . shutdown (
258
+ requiresCleanClose: requiresCleanClose,
259
+ queue: DispatchQueue ( label: " async-http-client.shutdown " )
260
+ ) { error in
261
+ shutdownError. didShutdown ( error)
262
+ }
263
+
264
+ let error = shutdownError. blockUntilShutdown ( )
265
+
266
+ if let error = error {
267
+ throw error
268
+ }
243
269
}
244
270
245
271
/// Shuts down the client and event loop gracefully.
0 commit comments