Skip to content

Commit

Permalink
Ensure Julia termintes when launcher terminates on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
davidanthoff committed Sep 2, 2024
1 parent 38df0a1 commit 95f1486
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ human-sort = "0.2.2"
regex = "1.10.5"

[target.'cfg(windows)'.dependencies]
windows = { version = "0.58.0", features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_System_Console", "Services_Store", "Foundation", "Foundation_Collections", "Web_Http", "Web_Http_Headers", "Storage_Streams", "Management_Deployment"] }
windows = { version = "0.58.0", features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_Security", "Win32_System_JobObjects", "Win32_System_Console", "Win32_System_Threading", "Services_Store", "Foundation", "Foundation_Collections", "Web_Http", "Web_Http_Headers", "Storage_Streams", "Management_Deployment"] }

[target.'cfg(target_os = "macos")'.dependencies]
reqwest = { version = "0.12.3", default-features = false, features = ["blocking", "native-tls", "socks"] }
Expand Down
55 changes: 50 additions & 5 deletions src/bin/julialauncher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@ use juliaup::config_file::{load_config_db, JuliaupConfig, JuliaupConfigChannel};
use juliaup::global_paths::get_paths;

Check warning on line 5 in src/bin/julialauncher.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/bin/julialauncher.rs
use juliaup::jsonstructs_versionsdb::JuliaupVersionDB;
use juliaup::versions_file::load_versions_db;
#[cfg(not(windows))]
use nix::{
sys::wait::{waitpid, WaitStatus},
unistd::{fork, ForkResult},
};
use normpath::PathExt;
#[cfg(not(windows))]
use std::os::unix::process::CommandExt;
use std::path::Path;
use std::path::PathBuf;
#[cfg(not(windows))]
use nix::{
sys::wait::{waitpid, WaitStatus},
unistd::{fork, ForkResult},
};

Check warning on line 17 in src/bin/julialauncher.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/juliaup/juliaup/src/bin/julialauncher.rs
#[cfg(windows)]
use std::os::windows::io::{AsRawHandle, RawHandle};
#[cfg(windows)]
use windows::Win32::System::{
JobObjects::{AssignProcessToJobObject, SetInformationJobObject},
Threading::GetCurrentProcess,
};

#[derive(thiserror::Error, Debug)]
#[error("{msg}")]
Expand Down Expand Up @@ -430,11 +437,49 @@ fn run_app() -> Result<i32> {
// process to handle things.
ctrlc::set_handler(|| ()).with_context(|| "Failed to set the Ctrl-C handler.")?;

let mut job_attr: windows::Win32::Security::SECURITY_ATTRIBUTES =
windows::Win32::Security::SECURITY_ATTRIBUTES::default();
let mut job_info: windows::Win32::System::JobObjects::JOBOBJECT_EXTENDED_LIMIT_INFORMATION =
windows::Win32::System::JobObjects::JOBOBJECT_EXTENDED_LIMIT_INFORMATION::default();

job_attr.bInheritHandle = false.into();
job_info.BasicLimitInformation.LimitFlags =
windows::Win32::System::JobObjects::JOB_OBJECT_LIMIT_BREAKAWAY_OK
| windows::Win32::System::JobObjects::JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
| windows::Win32::System::JobObjects::JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION
| windows::Win32::System::JobObjects::JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;

let job_handle = unsafe {
windows::Win32::System::JobObjects::CreateJobObjectW(
Some(&job_attr),
windows::core::PCWSTR::null(),
)
}?;
unsafe {
SetInformationJobObject(
job_handle,
windows::Win32::System::JobObjects::JobObjectExtendedLimitInformation,
&job_info as *const _ as *const std::os::raw::c_void,
std::mem::size_of_val(&job_info) as u32,
)
}?;

unsafe { AssignProcessToJobObject(job_handle, GetCurrentProcess()) }?;

let mut child_process = std::process::Command::new(julia_path)
.args(&new_args)
.spawn()
.with_context(|| "The Julia launcher failed to start Julia.")?; // TODO Maybe include the command we actually tried to start?

unsafe {
AssignProcessToJobObject(
job_handle,
std::mem::transmute::<RawHandle, windows::Win32::Foundation::HANDLE>(
child_process.as_raw_handle(),
),
)
}?;

run_versiondb_update(&config_file).with_context(|| "Failed to run version db update")?;

run_selfupdate(&config_file).with_context(|| "Failed to run selfupdate.")?;
Expand Down

0 comments on commit 95f1486

Please sign in to comment.