1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-22 06:09:25 -05:00
denoland-deno/cli/lsp/parent_process_checker.rs
David Sherret aecf989d43
chore(lsp): add --parent-pid <pid> flag (#11023)
This commit adds a new `--parent-pid <pid>` flag to `deno lsp` that when provided starts a task that checks for the existence of the provided process id (ex. vscode's) every 30 seconds. If the process doesn't exist (meaning the deno process has nothing interacting with it), then it terminates itself.
2021-06-17 19:57:58 -04:00

70 lines
1.8 KiB
Rust

// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use tokio::time::sleep;
use tokio::time::Duration;
/// Starts a task that will check for the existence of the
/// provided process id. Once that process no longer exists
/// it will terminate the current process.
pub fn start(parent_process_id: u32) {
tokio::task::spawn(async move {
loop {
sleep(Duration::from_secs(30)).await;
if !is_process_active(parent_process_id) {
eprintln!("Parent process lost. Exiting.");
std::process::exit(1);
}
}
});
}
#[cfg(unix)]
fn is_process_active(process_id: u32) -> bool {
unsafe {
// signal of 0 checks for the existence of the process id
libc::kill(process_id as i32, 0) == 0
}
}
#[cfg(windows)]
fn is_process_active(process_id: u32) -> bool {
use winapi::shared::minwindef::DWORD;
use winapi::shared::minwindef::FALSE;
use winapi::shared::ntdef::NULL;
use winapi::shared::winerror::WAIT_TIMEOUT;
use winapi::um::handleapi::CloseHandle;
use winapi::um::processthreadsapi::OpenProcess;
use winapi::um::synchapi::WaitForSingleObject;
use winapi::um::winnt::SYNCHRONIZE;
unsafe {
let process = OpenProcess(SYNCHRONIZE, FALSE, process_id as DWORD);
let result = if process == NULL {
false
} else {
WaitForSingleObject(process, 0) == WAIT_TIMEOUT
};
CloseHandle(process);
result
}
}
#[cfg(test)]
mod test {
use super::is_process_active;
use std::process::Command;
use test_util::deno_exe_path;
#[test]
fn process_active() {
// launch a long running process
let mut child = Command::new(deno_exe_path()).arg("lsp").spawn().unwrap();
let pid = child.id();
assert_eq!(is_process_active(pid), true);
child.kill().unwrap();
child.wait().unwrap();
assert_eq!(is_process_active(pid), false);
}
}