diff --git a/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift b/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift index c2c1c6965..bed2a6cc1 100644 --- a/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift +++ b/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift @@ -58,7 +58,7 @@ public final class JSONRPCConnection: Connection { /// The queue on which we send data. private let sendQueue: DispatchQueue = DispatchQueue(label: "jsonrpc-send-queue", qos: .userInitiated) - private let receiveIO: DispatchIO + private let inFD: FileHandle private let sendIO: DispatchIO private let messageRegistry: MessageRegistry @@ -86,7 +86,6 @@ public final class JSONRPCConnection: Connection { /// Buffer of received bytes that haven't been parsed. /// /// Access to this must be be guaranteed to be sequential to avoid data races. Currently, all access are - /// - The `receiveIO` handler: This is synchronized on `queue`. /// - `requestBufferIsEmpty`: Also synchronized on `queue`. private nonisolated(unsafe) var requestBuffer: [UInt8] = [] @@ -140,23 +139,12 @@ public final class JSONRPCConnection: Connection { #if os(Windows) let rawInFD = dispatch_fd_t(bitPattern: inFD._handle) + self.inFD = inFD #else let rawInFD = inFD.fileDescriptor #endif ioGroup.enter() - receiveIO = DispatchIO( - type: .stream, - fileDescriptor: rawInFD, - queue: queue, - cleanupHandler: { (error: Int32) in - if error != 0 { - logger.fault("IO error \(error)") - } - ioGroup.leave() - } - ) - #if os(Windows) let rawOutFD = dispatch_fd_t(bitPattern: outFD._handle) #else @@ -188,10 +176,6 @@ public final class JSONRPCConnection: Connection { } } - // We cannot assume the client will send us bytes in packets of any particular size, so set the lower limit to 1. - receiveIO.setLimit(lowWater: 1) - receiveIO.setLimit(highWater: Int.max) - sendIO.setLimit(lowWater: 1) sendIO.setLimit(highWater: Int.max) } @@ -293,27 +277,17 @@ public final class JSONRPCConnection: Connection { state = .running self.receiveHandler = receiveHandler self.closeHandler = closeHandler + } - receiveIO.read(offset: 0, length: Int.max, queue: queue) { done, data, errorCode in - guard errorCode == 0 else { - #if !os(Windows) - if errorCode != POSIXError.ECANCELED.rawValue { - logger.fault("IO error reading \(errorCode)") - } - #endif - if done { self.closeAssumingOnQueue() } - return - } - - if done { - self.closeAssumingOnQueue() - return - } - - guard let data = data, !data.isEmpty else { + self.inFD.readabilityHandler = { fileHandle in + let data = (try? fileHandle.read(upToCount: Int.max)) ?? Data() + if data.isEmpty { + fileHandle.readabilityHandler = nil + self.close() return - } + } + self.queue.sync { orLog("Writing input mirror file") { try self.inputMirrorFile?.write(contentsOf: data) } @@ -660,7 +634,6 @@ public final class JSONRPCConnection: Connection { logger.log("Closing JSONRPCConnection...") // Attempt to close the reader immediately; we do not need to accept remaining inputs. - receiveIO.close(flags: .stop) // Close the writer after it finishes outstanding work. sendIO.close() }