Skip to content

Commit b972883

Browse files
committed
Fix the Pipe handling on Windows to be correct
This actually addresses the real issue that was ignored earlier about pipes on Windows. The FileHandle cannot provide a non-owning file descriptor (the returned file descriptor would need to be explicitly `_close`'d by the receiver). Foundation now vends a `_handle` accessor to the OS primitive handle. Use this to create the dispatch loop for messaging. We now create the JSONRPCConnection from handles on Windows which actually should help enable running some of the tests on Windows as well.
1 parent 79795bf commit b972883

File tree

5 files changed

+23
-24
lines changed

5 files changed

+23
-24
lines changed

Sources/LSPTestSupport/TestJSONRPCConnection.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ public final class TestJSONRPCConnection {
2929
public init() {
3030
clientConnection = JSONRPCConnection(
3131
protocol: testMessageRegistry,
32-
inFD: serverToClient.fileHandleForReading.fileDescriptor,
33-
outFD: clientToServer.fileHandleForWriting.fileDescriptor
32+
inFD: serverToClient.fileHandleForReading,
33+
outFD: clientToServer.fileHandleForWriting
3434
)
3535

3636
serverConnection = JSONRPCConnection(
3737
protocol: testMessageRegistry,
38-
inFD: clientToServer.fileHandleForReading.fileDescriptor,
39-
outFD: serverToClient.fileHandleForWriting.fileDescriptor
38+
inFD: clientToServer.fileHandleForReading,
39+
outFD: serverToClient.fileHandleForWriting
4040
)
4141

4242
client = TestClient(server: clientConnection)

Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#if canImport(CDispatch)
14-
import CDispatch
14+
import struct CDispatch.dispatch_fd_t
1515
#endif
1616
import Dispatch
1717
import Foundation
1818
import LanguageServerProtocol
1919
import LSPLogging
20-
#if os(Windows)
21-
import ucrt
22-
#endif
2320

2421
/// A connection between a message handler (e.g. language server) in the same process as the connection object and a remote message handler (e.g. language client) that may run in another process using JSON RPC messages sent over a pair of in/out file descriptors.
2522
///
@@ -62,8 +59,8 @@ public final class JSONRPCConnection {
6259

6360
public init(
6461
protocol messageRegistry: MessageRegistry,
65-
inFD: Int32,
66-
outFD: Int32,
62+
inFD: FileHandle,
63+
outFD: FileHandle,
6764
syncRequests: Bool = false)
6865
{
6966
state = .created
@@ -72,26 +69,28 @@ public final class JSONRPCConnection {
7269

7370
let ioGroup = DispatchGroup()
7471

75-
ioGroup.enter()
7672
#if os(Windows)
77-
let inDesc: dispatch_fd_t = dispatch_fd_t(_get_osfhandle(inFD))
73+
let rawInFD = dispatch_fd_t(bitPattern: inFD._handle)
7874
#else
79-
let inDesc: Int32 = Int32(inFD)
75+
let rawInFD = inFD.fileDescriptor
8076
#endif
81-
receiveIO = DispatchIO(type: .stream, fileDescriptor: inDesc, queue: queue) { (error: Int32) in
77+
78+
ioGroup.enter()
79+
receiveIO = DispatchIO(type: .stream, fileDescriptor: rawInFD, queue: queue) { (error: Int32) in
8280
if error != 0 {
8381
log("IO error \(error)", level: .error)
8482
}
8583
ioGroup.leave()
8684
}
8785

88-
ioGroup.enter()
8986
#if os(Windows)
90-
let outDesc: dispatch_fd_t = dispatch_fd_t(_get_osfhandle(outFD))
87+
let rawOutFD = dispatch_fd_t(bitPattern: outFD._handle)
9188
#else
92-
let outDesc: Int32 = Int32(outFD)
89+
let rawOutFD = outFD.fileDescriptor
9390
#endif
94-
sendIO = DispatchIO(type: .stream, fileDescriptor: outDesc, queue: sendQueue) { (error: Int32) in
91+
92+
ioGroup.enter()
93+
sendIO = DispatchIO(type: .stream, fileDescriptor: rawOutFD, queue: sendQueue) { (error: Int32) in
9594
if error != 0 {
9695
log("IO error \(error)", level: .error)
9796
}

Sources/SKCore/BuildServerBuildSystem.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ private func makeJSONRPCBuildServer(client: MessageHandler, serverPath: Absolute
250250

251251
let connection = JSONRPCConnection(
252252
protocol: BuildServerProtocol.bspRegistry,
253-
inFD: serverToClient.fileHandleForReading.fileDescriptor,
254-
outFD: clientToServer.fileHandleForWriting.fileDescriptor
253+
inFD: serverToClient.fileHandleForReading,
254+
outFD: clientToServer.fileHandleForWriting
255255
)
256256

257257
connection.start(receiveHandler: client) {

Sources/SourceKitLSP/Clang/ClangLanguageServer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,8 @@ func makeJSONRPCClangServer(
293293

294294
let connection = JSONRPCConnection(
295295
protocol: MessageRegistry.lspProtocol,
296-
inFD: clangdToUs.fileHandleForReading.fileDescriptor,
297-
outFD: usToClangd.fileHandleForWriting.fileDescriptor
296+
inFD: clangdToUs.fileHandleForReading,
297+
outFD: usToClangd.fileHandleForWriting
298298
)
299299

300300
let connectionToClient = LocalConnection()

Sources/sourcekit-lsp/main.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ struct Main: ParsableCommand {
161161

162162
let clientConnection = JSONRPCConnection(
163163
protocol: MessageRegistry.lspProtocol,
164-
inFD: fileno(stdin),
165-
outFD: realStdout,
164+
inFD: FileHandle(fileDescriptor: fileno(stdin), closeOnDealloc: false),
165+
outFD: FileHandle.standardInput,
166166
syncRequests: syncRequests
167167
)
168168

0 commit comments

Comments
 (0)