Skip to content

Commit 317a662

Browse files
committed
chore: improve client health checking (windows)
1 parent 699f5c6 commit 317a662

File tree

3 files changed

+35
-8
lines changed

3 files changed

+35
-8
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/els/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ molc = { version = "0.3" }
3030
serde = { version = "1.0", features = ["derive"] }
3131
serde_json = "1.0.85"
3232
lsp-types = { version = "0.93.2", features = ["proposed"] }
33+
34+
[target.'cfg(unix)'.dependencies]
3335
libc = "0.2"
36+
[target.'cfg(windows)'.dependencies]
37+
windows = { version = "0.58", features = ["Win32_System_Threading"] }
3438

3539
[dev-dependencies]
3640
erg_proc_macros = { workspace = true }

crates/els/diagnostics.rs

+30-8
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,37 @@ use crate::server::{DefaultFeatures, ELSResult, RedirectableStdout, Server};
3434
use crate::server::{ASK_AUTO_SAVE_ID, HEALTH_CHECKER_ID};
3535
use crate::util::{self, NormalizedUrl};
3636

37-
pub fn is_parent_alive(parent_pid: i32) -> bool {
37+
#[cfg(unix)]
38+
pub fn is_process_alive(pid: i32) -> bool {
3839
unsafe {
3940
// sig 0: check if the process exists
40-
let alive = libc::kill(parent_pid, 0);
41+
let alive = libc::kill(pid, 0);
4142
alive == 0
4243
}
4344
}
45+
#[cfg(windows)]
46+
pub fn is_process_alive(pid: i32) -> bool {
47+
unsafe {
48+
use windows::Win32::System::Threading::{
49+
GetExitCodeProcess, OpenProcess, PROCESS_QUERY_INFORMATION,
50+
};
51+
52+
const STILL_ACTIVE: u32 = 0x103u32;
53+
54+
let Ok(handle) = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid as u32) else {
55+
return false;
56+
};
57+
let mut code = 0;
58+
let Ok(_) = GetExitCodeProcess(handle, &mut code) else {
59+
return false;
60+
};
61+
code == STILL_ACTIVE
62+
}
63+
}
64+
#[cfg(all(not(windows), not(unix)))]
65+
pub fn is_process_alive(_pid: i32) -> bool {
66+
false
67+
}
4468

4569
#[derive(Debug)]
4670
pub enum BuildASTError {
@@ -531,6 +555,9 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
531555
if self.stdout_redirect.is_some() {
532556
return;
533557
}
558+
let Some(client_pid) = self.init_params.process_id.map(|x| x as i32) else {
559+
return;
560+
};
534561
let _self = self.clone();
535562
// FIXME: close this thread when the server is restarted
536563
spawn_new_thread(
@@ -554,11 +581,6 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
554581
},
555582
"start_client_health_checker_sender",
556583
);
557-
let parent_pid = self
558-
.init_params
559-
.process_id
560-
.map(|x| x as i32)
561-
.unwrap_or_else(|| unsafe { libc::getppid() });
562584
spawn_new_thread(
563585
move || {
564586
loop {
@@ -575,7 +597,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
575597
// _log!(self, "Restart the server");
576598
// send_error_info("Something went wrong, ELS has been restarted").unwrap();
577599
// self_.restart();
578-
if !is_parent_alive(parent_pid) {
600+
if !is_process_alive(client_pid) {
579601
lsp_log!("Client seems to be dead");
580602
panic!("Client seems to be dead");
581603
}

0 commit comments

Comments
 (0)