mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user