From 6cae73eb488c2f66bfe586a8dd6a756f36630680 Mon Sep 17 00:00:00 2001 From: Carlos Cabanero Date: Tue, 9 Apr 2024 16:36:26 -0400 Subject: [PATCH] Properly close DispatchStreams - We think that not closing these explicitely is causing the main descriptor to be in a "random" state. Other applications may fail on lock or just skip a read because the descriptor may be set as non-blocking, etc... - Tested opening ssh and then opening mosh. The mosh client would randomly terminate. We think this was also causing random ios_exit issues and Blink's prompt crashes. --- SSH/DispatchStreams.swift | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/SSH/DispatchStreams.swift b/SSH/DispatchStreams.swift index 19e1c3cc9..09d11cf41 100644 --- a/SSH/DispatchStreams.swift +++ b/SSH/DispatchStreams.swift @@ -50,8 +50,10 @@ public enum DispatchStreamError: Error { public class DispatchOutputStream: Writer { let stream: DispatchIO let queue: DispatchQueue + var fd: Int32? public init(stream: Int32) { + self.fd = stream self.queue = DispatchQueue(label: "file-\(stream)") self.stream = DispatchIO(type: .stream, fileDescriptor: stream, queue: self.queue, cleanupHandler: { error in print("Dispatch closed with \(error)") @@ -82,15 +84,26 @@ public class DispatchOutputStream: Writer { } public func close() { - stream.close(flags: .stop) + if self.fd != nil { + stream.close(flags: .stop) + self.fd = nil + } + } + + deinit { + if self.fd != nil { + stream.close(flags: .stop) + } } } public class DispatchInputStream { let stream: DispatchIO let queue: DispatchQueue + var fd: Int32? public init(stream: Int32) { + self.fd = stream self.queue = DispatchQueue(label: "file-\(stream)") self.stream = DispatchIO(type: .stream, fileDescriptor: stream, queue: self.queue, cleanupHandler: { error in print("Dispatch \(error)") @@ -99,7 +112,16 @@ public class DispatchInputStream { } public func close() { - stream.close(flags: .stop) + if self.fd != nil { + stream.close(flags: .stop) + self.fd = nil + } + } + + deinit { + if self.fd != nil { + stream.close(flags: .stop) + } } }