internal: Use a process group for flycheck

This commit is contained in:
Lukas Wirth 2022-11-05 16:28:04 +01:00
parent e47460b208
commit 1dcc25a70a
3 changed files with 36 additions and 8 deletions

24
Cargo.lock generated
View File

@ -221,6 +221,16 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "command-group"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7a8a86f409b4a59df3a3e4bee2de0b83f1755fdd2a25e3a9684c396fc4bed2c"
dependencies = [
"nix",
"winapi",
]
[[package]] [[package]]
name = "countme" name = "countme"
version = "3.0.1" version = "3.0.1"
@ -390,6 +400,7 @@ name = "flycheck"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"cargo_metadata", "cargo_metadata",
"command-group",
"crossbeam-channel", "crossbeam-channel",
"jod-thread", "jod-thread",
"paths", "paths",
@ -970,6 +981,19 @@ dependencies = [
"windows-sys 0.28.0", "windows-sys 0.28.0",
] ]
[[package]]
name = "nix"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
dependencies = [
"bitflags",
"cc",
"cfg-if",
"libc",
"memoffset",
]
[[package]] [[package]]
name = "notify" name = "notify"
version = "5.0.0" version = "5.0.0"

View File

@ -17,6 +17,7 @@ rustc-hash = "1.1.0"
serde = { version = "1.0.137", features = ["derive"] } serde = { version = "1.0.137", features = ["derive"] }
serde_json = "1.0.86" serde_json = "1.0.86"
jod-thread = "0.1.2" jod-thread = "0.1.2"
command-group = "1.0.8"
toolchain = { path = "../toolchain", version = "0.0.0" } toolchain = { path = "../toolchain", version = "0.0.0" }
stdx = { path = "../stdx", version = "0.0.0" } stdx = { path = "../stdx", version = "0.0.0" }

View File

@ -10,11 +10,12 @@ use std::{
time::Duration, time::Duration,
}; };
use command_group::{CommandGroup, GroupChild};
use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
use paths::AbsPathBuf; use paths::AbsPathBuf;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use serde::Deserialize; use serde::Deserialize;
use stdx::{process::streaming_output, JodChild}; use stdx::process::streaming_output;
pub use cargo_metadata::diagnostic::{ pub use cargo_metadata::diagnostic::{
Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan, Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
@ -359,6 +360,8 @@ impl FlycheckActor {
} }
} }
struct JodChild(GroupChild);
/// A handle to a cargo process used for fly-checking. /// A handle to a cargo process used for fly-checking.
struct CargoHandle { struct CargoHandle {
/// The handle to the actual cargo process. As we cannot cancel directly from with /// The handle to the actual cargo process. As we cannot cancel directly from with
@ -371,10 +374,10 @@ struct CargoHandle {
impl CargoHandle { impl CargoHandle {
fn spawn(mut command: Command) -> std::io::Result<CargoHandle> { fn spawn(mut command: Command) -> std::io::Result<CargoHandle> {
command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
let mut child = JodChild::spawn(command)?; let mut child = command.group_spawn().map(JodChild)?;
let stdout = child.stdout.take().unwrap(); let stdout = child.0.inner().stdout.take().unwrap();
let stderr = child.stderr.take().unwrap(); let stderr = child.0.inner().stderr.take().unwrap();
let (sender, receiver) = unbounded(); let (sender, receiver) = unbounded();
let actor = CargoActor::new(sender, stdout, stderr); let actor = CargoActor::new(sender, stdout, stderr);
@ -386,13 +389,13 @@ impl CargoHandle {
} }
fn cancel(mut self) { fn cancel(mut self) {
let _ = self.child.kill(); let _ = self.child.0.kill();
let _ = self.child.wait(); let _ = self.child.0.wait();
} }
fn join(mut self) -> io::Result<()> { fn join(mut self) -> io::Result<()> {
let _ = self.child.kill(); let _ = self.child.0.kill();
let exit_status = self.child.wait()?; let exit_status = self.child.0.wait()?;
let (read_at_least_one_message, error) = self.thread.join()?; let (read_at_least_one_message, error) = self.thread.join()?;
if read_at_least_one_message || exit_status.success() { if read_at_least_one_message || exit_status.success() {
Ok(()) Ok(())