diff --git a/Cargo.lock b/Cargo.lock index f1f52e4..335bdcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,9 +157,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549" dependencies = [ "jobserver", "libc", @@ -255,7 +255,6 @@ dependencies = [ "reqwest", "serde", "serde_json", - "sysinfo", "tokio", "tracing", "tracing-appender", @@ -263,7 +262,7 @@ dependencies = [ "tracing-futures", "tracing-subscriber", "url", - "windows 0.58.0", + "windows", "zstd", ] @@ -993,15 +992,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "ntapi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" -dependencies = [ - "winapi", -] - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1530,18 +1520,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.204" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" dependencies = [ "proc-macro2", "quote", @@ -1689,20 +1679,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -[[package]] -name = "sysinfo" -version = "0.30.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" -dependencies = [ - "cfg-if", - "core-foundation-sys", - "libc", - "ntapi", - "once_cell", - "windows 0.52.0", -] - [[package]] name = "system-configuration" version = "0.5.1" @@ -2200,32 +2176,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ + "windows-core", "windows-targets 0.52.6", ] diff --git a/Cargo.toml b/Cargo.toml index 354c59a..bc4a470 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,8 +45,11 @@ url = "2" zstd = "0.13" [target.'cfg(windows)'.dependencies] -sysinfo = { version = "0.30", default-features = false } -windows = { version = "0.58", features = ["Win32_System_Console"] } +windows = { version = "0.58", features = [ + "Win32_System_Console", + "Win32_System_Threading", + "Win32_System_Diagnostics_ToolHelp", +] } [build-dependencies] bindgen = "0.69" diff --git a/src/cef_exe.rs b/src/cef_exe.rs index ab35e5e..3fc4832 100644 --- a/src/cef_exe.rs +++ b/src/cef_exe.rs @@ -49,56 +49,72 @@ fn main() { // // on mac, i can't seem to reproduce the child process staying after `killall -9 ClassiCube` #[cfg(target_os = "windows")] - let stop_parent_watcher = { - use std::{ - sync::mpsc::{self, RecvTimeoutError}, - thread, - time::Duration, + { + use std::thread; + + use windows::{ + core::Error, + Win32::{ + Foundation::{CloseHandle, FALSE, HANDLE}, + System::{ + Diagnostics::ToolHelp::{ + CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, + TH32CS_SNAPPROCESS, + }, + Threading::{ + GetCurrentProcessId, OpenProcess, WaitForSingleObject, INFINITE, + PROCESS_SYNCHRONIZE, + }, + }, + }, }; - use sysinfo::{Pid, ProcessRefreshKind, RefreshKind, System}; - - const PROCESS_CHECK_INTERVAL: Duration = Duration::from_secs(2); - - let (kill_thread_tx, kill_thread_rx) = mpsc::channel(); - let thread_handle = thread::spawn(move || { - let mut system = System::new_with_specifics( - RefreshKind::new().with_processes(ProcessRefreshKind::new()), - ); - let my_pid = Pid::from_u32(process::id()); - - let parent_pid = system.process(my_pid).and_then(|process| process.parent()); - debug!(?my_pid, ?parent_pid); + thread::spawn(move || { + unsafe fn get_parent_handle() -> Result<(HANDLE, u32), Error> { + let current_process_id = GetCurrentProcessId(); - if let Some(parent_pid) = parent_pid { - debug!("watching for parent {:?} to die", parent_pid); + let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)?; + let mut process_entry = PROCESSENTRY32 { + dwSize: core::mem::size_of::() as _, + ..Default::default() + }; + Process32First(snapshot, &mut process_entry)?; loop { - if !system.refresh_process_specifics(parent_pid, ProcessRefreshKind::new()) { - warn!("parent {:?} died; exiting", parent_pid); - process::exit(1); + if process_entry.th32ProcessID == current_process_id { + break; } - match kill_thread_rx.recv_timeout(PROCESS_CHECK_INTERVAL) { - Err(RecvTimeoutError::Timeout) => {} - Ok(_) => { - debug!("dying"); - return; - } - err => { - err.unwrap(); - return; - } + Process32Next(snapshot, &mut process_entry)?; + } + CloseHandle(snapshot)?; + + Ok(( + OpenProcess( + PROCESS_SYNCHRONIZE, + FALSE, + process_entry.th32ParentProcessID, + )?, + process_entry.th32ParentProcessID, + )) + } + + match unsafe { get_parent_handle() } { + Ok((parent_handle, parent_pid)) => { + debug!(?parent_handle, parent_pid, "watching for parent to die"); + let result = unsafe { WaitForSingleObject(parent_handle, INFINITE) }; + warn!(?result, ?parent_handle, parent_pid, "parent died; exiting"); + if let Err(e) = unsafe { CloseHandle(parent_handle) } { + warn!(?e, "CloseHandle"); } + process::exit(1); + } + Err(e) => { + warn!(?e, "get_parent_handle"); } } }); - - move || { - kill_thread_tx.send(()).unwrap(); - thread_handle.join().unwrap(); - } - }; + } let arg_v = env::args() .map(|s| CString::new(s).unwrap()) @@ -110,8 +126,5 @@ fn main() { let ret = unsafe { cef_interface_execute_process(arg_c, arg_v.as_ptr()) }; warn!(?ret, "cef_interface_execute_process"); - #[cfg(target_os = "windows")] - stop_parent_watcher(); - process::exit(ret); }