Skip to content

Commit 5449a2a

Browse files
committed
[jsonrpc] Workaround file descriptor lifetime issue
We should solve this in the JSONRPCConnection itself, but in the meantime workaround by keeping pipes alive until the connection has closed.
1 parent 4a86e81 commit 5449a2a

File tree

5 files changed

+39
-21
lines changed

5 files changed

+39
-21
lines changed

Sources/LSPTestSupport/TestJSONRPCConnection.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -18,7 +18,7 @@ import XCTest
1818
// Workaround ambiguity with Foundation.
1919
public typealias Notification = LanguageServerProtocol.Notification
2020

21-
public struct TestJSONRPCConnection {
21+
public final class TestJSONRPCConnection {
2222
public let clientToServer: Pipe = Pipe()
2323
public let serverToClient: Pipe = Pipe()
2424
public let client: TestClient
@@ -27,11 +27,6 @@ public struct TestJSONRPCConnection {
2727
public let serverConnection: JSONRPCConnection
2828

2929
public init() {
30-
// FIXME: DispatchIO doesn't like when the Pipes close behind its back even after the tests
31-
// finish. Until we fix the lifetime, leak.
32-
_ = Unmanaged.passRetained(clientToServer)
33-
_ = Unmanaged.passRetained(serverToClient)
34-
3530
clientConnection = JSONRPCConnection(
3631
protocol: testMessageRegistry,
3732
inFD: serverToClient.fileHandleForReading.fileDescriptor,
@@ -47,8 +42,16 @@ public struct TestJSONRPCConnection {
4742
client = TestClient(server: clientConnection)
4843
server = TestServer(client: serverConnection)
4944

50-
clientConnection.start(receiveHandler: client)
51-
serverConnection.start(receiveHandler: server)
45+
clientConnection.start(receiveHandler: client) {
46+
// FIXME: keep the pipes alive until we close the connection. This
47+
// should be fixed systemically.
48+
withExtendedLifetime(self) {}
49+
}
50+
serverConnection.start(receiveHandler: server) {
51+
// FIXME: keep the pipes alive until we close the connection. This
52+
// should be fixed systemically.
53+
withExtendedLifetime(self) {}
54+
}
5255
}
5356

5457
public func close() {

Sources/SKCore/BuildServerBuildSystem.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ private func makeJSONRPCBuildServer(client: MessageHandler, serverPath: Absolute
254254
outFD: clientToServer.fileHandleForWriting.fileDescriptor
255255
)
256256

257-
connection.start(receiveHandler: client)
257+
connection.start(receiveHandler: client) {
258+
// FIXME: keep the pipes alive until we close the connection. This
259+
// should be fixed systemically.
260+
withExtendedLifetime((clientToServer, serverToClient)) {}
261+
}
258262
let process = Foundation.Process()
259263

260264
if #available(OSX 10.13, *) {

Sources/SKTestSupport/TestServer.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -63,11 +63,6 @@ public struct TestSourceKitServer {
6363
let clientToServer: Pipe = Pipe()
6464
let serverToClient: Pipe = Pipe()
6565

66-
// FIXME: DispatchIO doesn't like when the Pipes close behind its back even after the tests
67-
// finish. Until we fix the lifetime, leak.
68-
_ = Unmanaged.passRetained(clientToServer)
69-
_ = Unmanaged.passRetained(serverToClient)
70-
7166
let clientConnection = JSONRPCConnection(
7267
protocol: MessageRegistry.lspProtocol,
7368
inFD: serverToClient.fileHandleForReading.fileDescriptor,
@@ -84,8 +79,16 @@ public struct TestSourceKitServer {
8479
serverConnection.close()
8580
})
8681

87-
clientConnection.start(receiveHandler: client)
88-
serverConnection.start(receiveHandler: server!)
82+
clientConnection.start(receiveHandler: client) {
83+
// FIXME: keep the pipes alive until we close the connection. This
84+
// should be fixed systemically.
85+
withExtendedLifetime((clientToServer, serverToClient)) {}
86+
}
87+
serverConnection.start(receiveHandler: server!) {
88+
// FIXME: keep the pipes alive until we close the connection. This
89+
// should be fixed systemically.
90+
withExtendedLifetime((clientToServer, serverToClient)) {}
91+
}
8992

9093
connImpl = .jsonrpc(
9194
clientToServer: clientToServer,

Sources/SourceKitLSP/Clang/ClangLanguageServer.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -247,7 +247,11 @@ func makeJSONRPCClangServer(
247247
clang: toolchain.clang)
248248

249249
connectionToClient.start(handler: client)
250-
connection.start(receiveHandler: client)
250+
connection.start(receiveHandler: client) {
251+
// FIXME: keep the pipes alive until we close the connection. This
252+
// should be fixed systemically.
253+
withExtendedLifetime((clientToServer, serverToClient)) {}
254+
}
251255

252256
let process = Foundation.Process()
253257

Tests/LanguageServerProtocolJSONRPCTests/ConnectionTests.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -237,6 +237,10 @@ class ConnectionTests: XCTestCase {
237237
conn.start(receiveHandler: DummyHandler(), closeHandler: {
238238
// We get an error from XCTest if this is fulfilled more than once.
239239
expectation.fulfill()
240+
241+
// FIXME: keep the pipes alive until we close the connection. This
242+
// should be fixed systemically.
243+
withExtendedLifetime((to, from)) {}
240244
})
241245

242246
to.fileHandleForWriting.closeFile()

0 commit comments

Comments
 (0)