fix: failed to receive shutdown signal on windows (#5533)

* fix: receive shutdown signal failed on windows

* docs: update Changelog.md

* chore: update

* fix: use tokio runtime to handle shutdown signal

* docs: update Changelog.md

* fix: move tauri dependency to the correct section in Cargo.toml

* fix: remove unused exit handling code in run function

* fix(clash-verge-signal): use global runtime to avoid tokio runtime panic on unix

* chore: update tauri-plugin-mihomo deps

* fix: handle macOS exit event to ensure proper application termination

---------

Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
oomeow
2025-11-22 22:36:00 +08:00
committed by GitHub
parent 687530a9cd
commit cbab199f80
11 changed files with 130 additions and 106 deletions

View File

@@ -1,13 +1,32 @@
use std::sync::OnceLock;
use clash_verge_logging::{Type, logging};
#[cfg(unix)]
mod unix;
#[cfg(windows)]
mod windows;
pub(crate) static RUNTIME: OnceLock<Option<tokio::runtime::Runtime>> = OnceLock::new();
pub fn register<F, Fut>(#[cfg(windows)] app_handle: &tauri::AppHandle, f: F)
where
F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future + Send + 'static,
{
RUNTIME.get_or_init(|| match tokio::runtime::Runtime::new() {
Ok(rt) => Some(rt),
Err(e) => {
logging!(
info,
Type::System,
"register shutdown signal failed, create tokio runtime error: {}",
e
);
None
}
});
#[cfg(unix)]
unix::register(f);

View File

@@ -6,39 +6,49 @@ use signal_hook::{
use clash_verge_logging::{Type, logging, logging_error};
use crate::RUNTIME;
pub fn register<F, Fut>(f: F)
where
F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future + Send + 'static,
{
tauri::async_runtime::spawn(async move {
let signals = [SIGTERM, SIGINT, SIGHUP];
if let Some(Some(rt)) = RUNTIME.get() {
rt.spawn(async move {
let signals = [SIGTERM, SIGINT, SIGHUP];
let mut sigs = match Signals::new(signals) {
Ok(s) => s,
Err(e) => {
logging!(error, Type::System, "注册信号处理器失败: {}", e);
return;
}
};
for signal in &mut sigs {
let signal_to_str = |signal: i32| match signal {
SIGTERM => "SIGTERM",
SIGINT => "SIGINT",
SIGHUP => "SIGHUP",
_ => "UNKNOWN",
let mut sigs = match Signals::new(signals) {
Ok(s) => s,
Err(e) => {
logging!(error, Type::System, "注册信号处理器失败: {}", e);
return;
}
};
logging!(info, Type::System, "捕获到信号 {}", signal_to_str(signal));
for signal in &mut sigs {
let signal_to_str = |signal| match signal {
SIGTERM => "SIGTERM",
SIGINT => "SIGINT",
SIGHUP => "SIGHUP",
_ => "UNKNOWN",
};
f().await;
logging!(info, Type::System, "捕获到信号 {}", signal_to_str(signal));
logging_error!(
Type::System,
"信号 {:?} 默认处理失败",
low_level::emulate_default_handler(signal)
);
}
});
f().await;
logging_error!(
Type::System,
"信号 {:?} 默认处理失败",
low_level::emulate_default_handler(signal)
);
}
});
} else {
logging!(
error,
Type::System,
"register shutdown signal failed, RUNTIME is not available"
);
}
}

View File

@@ -12,6 +12,8 @@ use windows_sys::Win32::{
use clash_verge_logging::{Type, logging};
use crate::RUNTIME;
// code refer to:
// global-hotkey (https://github.com/tauri-apps/global-hotkey)
// Global Shortcut (https://github.com/tauri-apps/plugins-workspace/tree/v2/plugins/global-shortcut)
@@ -56,11 +58,19 @@ unsafe extern "system" fn shutdown_proc(
}
WM_ENDSESSION => {
if let Some(handler) = SHUTDOWN_HANDLER.get() {
tauri::async_runtime::block_on(async {
logging!(info, Type::System, "Session ended, system shutting down.");
handler().await;
logging!(info, Type::System, "resolved reset finished");
});
if let Some(Some(rt)) = RUNTIME.get() {
rt.block_on(async {
logging!(info, Type::System, "Session ended, system shutting down.");
handler().await;
logging!(info, Type::System, "resolved reset finished");
});
} else {
logging!(
error,
Type::System,
"handle shutdown signal failed, RUNTIME is not available"
);
}
} else {
logging!(
error,