Cancellation handler for receiveData() function (#1371)

Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
This commit is contained in:
jake-b 2025-09-03 17:47:54 -04:00 committed by GitHub
parent 194f62850c
commit 077cd73129
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -93,19 +93,31 @@ actor TCPConnection: Connection {
}
private func receiveData(min: Int, max: Int) async throws -> Data {
try await withCheckedThrowingContinuation { cont in
connection?.receive(minimumIncompleteLength: min, maximumLength: max) { content, _, isComplete, error in
if let error = error {
cont.resume(throwing: error)
return
let capturedConnection = connection
return try await withTaskCancellationHandler {
try await withCheckedThrowingContinuation { cont in
connection?.receive(minimumIncompleteLength: min, maximumLength: max) { content, _, isComplete, error in
if let error = error {
cont.resume(throwing: error)
return
}
if isComplete {
// cont.resume(returning: Data())
cont.resume(throwing: AccessoryError.disconnected("Error while receiving data"))
return
}
if let content {
cont.resume(returning: content)
} else {
cont.resume(returning: Data())
}
}
if isComplete {
// cont.resume(returning: Data())
cont.resume(throwing: AccessoryError.disconnected("Error while receiving data"))
return
}
cont.resume(returning: content ?? Data())
}
} onCancel: {
// onCancel cannot directly resume the continuation (it doesnt know if its already been resumed).
// A safe pattern is to cancel the underlying NWConnection. That forces the receive completion
// handler to fire with an error, where you can safely resume the continuation.
capturedConnection?.cancel()
}
}
@ -225,3 +237,4 @@ actor TCPConnection: Connection {
}
}