mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
When SourceKit-LSP is shut down, we should make sure that we don’t leave behind child processes, which will become orphans after SourceKit-LSP has terminated. What’s worse, when SourceKit-LSP has exited, these processes might not have any process to read their stdout/stderr, which can lead to them running indefinitely. This change does not cover the termination of subprocess trees. For example, if we launch `swift build` and need to kill it because it doesn’t honor SIGINT, its child processes will still live on. Similarly, if we kill a BSP server, its child processes might live on. Fixing this is a drastically bigger endeavor, likely requiring changes to Foundation and/or TSC. I filed https://github.com/swiftlang/sourcekit-lsp/issues/2080 for it.
39 lines
1.4 KiB
Swift
39 lines
1.4 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
package import Foundation
|
|
|
|
extension Foundation.Process {
|
|
/// If the process has not exited after `duration`, terminate it.
|
|
package func terminateIfRunning(after duration: Duration, pollInterval: Duration = .milliseconds(5)) async throws {
|
|
for _ in 0..<Int(duration.seconds / pollInterval.seconds) {
|
|
if !self.isRunning {
|
|
break
|
|
}
|
|
try await Task.sleep(for: pollInterval)
|
|
}
|
|
if self.isRunning {
|
|
self.terminate()
|
|
}
|
|
}
|
|
|
|
/// On Posix platforms, send a SIGKILL to the process. On Windows, terminate the process.
|
|
package func terminateImmediately() {
|
|
// TODO: We should also terminate all child processes (https://github.com/swiftlang/sourcekit-lsp/issues/2080)
|
|
#if os(Windows)
|
|
self.terminate()
|
|
#else
|
|
Foundation.kill(processIdentifier, SIGKILL) // ignore-unacceptable-language
|
|
#endif
|
|
}
|
|
}
|