Close a handle inside a lock (#257)

Improves https://github.com/apple/containerization/pull/245. A potential
deadlock risk was not proven. This PR moves the closing operation inside
the lock to prevent leaking an unclosed handle in case of an error.
This commit is contained in:
Dmitry Kovba
2025-08-11 12:26:31 -04:00
committed by GitHub
parent 259c841591
commit 7b00f39140
@@ -179,25 +179,24 @@ extension Socket {
}
public func close() throws {
let (handleToClose, sourceToCancel) = state.withLock { currentState -> (FileHandle?, DispatchSourceRead?) in
try state.withLock { currentState in
guard let handle = currentState.handle else {
// Already closed.
return (nil, nil)
return
}
let acceptSource = currentState.acceptSource
acceptSource?.cancel()
try handle.close()
currentState = State(
socketState: currentState.socketState,
handle: nil,
type: currentState.type,
acceptSource: nil
)
return (handle, currentState.acceptSource)
}
// Close outside the lock to avoid a deadlock.
sourceToCancel?.cancel()
try handleToClose?.close()
}
public func write(data: any DataProtocol) throws -> Int {