#![cfg_attr(docsrs, feature(doc_cfg))]
use std::{env, process::Command};
use log::{error, info};
use tokio::task;
pub use tokio_util::sync::CancellationToken;
#[cfg(unix)]
mod unix;
#[cfg(windows)]
mod windows;
#[cfg(unix)]
use unix::{setup_process_detachment, wait_reload};
#[cfg(windows)]
use windows::{setup_process_detachment, wait_reload};
async fn spawn(token: CancellationToken) {
let current_exe = match env::current_exe() {
Ok(path) => path,
Err(e) => {
error!("NO EXE PATH {e}");
return;
}
};
let args: Vec<String> = env::args().collect();
info!("reload_self : {} {:?}", current_exe.display(), &args[1..]);
let mut command = Command::new(current_exe);
command.args(&args[1..]);
setup_process_detachment(&mut command);
match command.spawn() {
Ok(child) => {
let pid = child.id();
info!("reload_self : PID {pid} ; 母进程开始关闭");
token.cancel();
}
Err(e) => {
error!("reload_self : {e}");
}
}
}
pub fn listen() -> Result<CancellationToken, std::io::Error> {
let token = CancellationToken::new();
let token_for_signal = token.clone();
task::spawn(async move {
wait_reload().await;
spawn(token_for_signal).await;
});
Ok(token)
}