-
Notifications
You must be signed in to change notification settings - Fork 175
Description
Bug
When NetworkTransport is deallocated while an async send(), sendHeartbeat(), or receiveData() operation is in-flight, the CheckedContinuation inside the NWConnection completion handler is never resumed — causing a permanent deadlock.
Root Cause
The .contentProcessed completion closures capture [weak self] but do not capture continuation directly. When self becomes nil in the completion handler, the guard let self else { return } exits without resuming the continuation.
This violates Swift's CheckedContinuation contract: a continuation must be resumed exactly once. Never resuming causes the caller to hang forever. In debug builds (Swift 6.3), this produces a runtime warning.
Affected Methods
NetworkTransport.send(_ message: Data)—.contentProcessedcompletionNetworkTransport.sendHeartbeat()—.contentProcessedcompletionNetworkTransport.receiveData()—connection.receivecompletion (strong self capture inconsistency)
Reproduction
- Create a
NetworkTransportconnection - Start a
send()call - Deallocate the transport before the NWConnection completion fires
- The caller hangs indefinitely
Environment
- Swift 6.3 (also affects earlier versions, but Swift 6.3 strict concurrency makes it more visible)
- Network framework (NWConnection)
Fix
Capture continuation directly in completion closures alongside [weak self], and resume with an error in the guard's else branch. See PR #213.