refactor(signal): migrate signal to handling async in unix and remove signal-hook dependency

This commit is contained in:
Tunglies
2025-12-06 06:38:52 +08:00
parent d0c8f7fcc1
commit d28075221c
7 changed files with 63 additions and 38 deletions

1
Cargo.lock generated
View File

@@ -1285,7 +1285,6 @@ version = "0.1.0"
dependencies = [
"clash-verge-logging",
"log",
"signal-hook 0.3.18",
"tauri",
"tokio",
"windows-sys 0.61.2",

View File

@@ -61,6 +61,7 @@
- 优化应用重启/退出时的资源清理性能, 大幅缩短执行时间
- 优化 WebSocket 连接机制
- 改进旧版 Service 需要重新安装检测流程
- 优化 macOS 和 Linux 信号处理
</details>

View File

@@ -18,6 +18,7 @@ pub enum Type {
Config,
Setup,
System,
SystemSignal,
Service,
Hotkey,
Window,
@@ -42,6 +43,7 @@ impl fmt::Display for Type {
Self::Config => write!(f, "[Config]"),
Self::Setup => write!(f, "[Setup]"),
Self::System => write!(f, "[System]"),
Self::SystemSignal => write!(f, "[SysSignal]"),
Self::Service => write!(f, "[Service]"),
Self::Hotkey => write!(f, "[Hotkey]"),
Self::Window => write!(f, "[Window]"),

View File

@@ -9,9 +9,6 @@ clash-verge-logging = { workspace = true }
log = { workspace = true }
tokio = { workspace = true }
[target.'cfg(unix)'.dependencies]
signal-hook = "0.3.18"
[target.'cfg(windows)'.dependencies]
tauri = { workspace = true }
windows-sys = { version = "0.61.2", features = [

View File

@@ -19,7 +19,7 @@ where
Err(e) => {
logging!(
info,
Type::System,
Type::SystemSignal,
"register shutdown signal failed, create tokio runtime error: {}",
e
);

View File

@@ -1,10 +1,5 @@
use signal_hook::{
consts::{SIGHUP, SIGINT, SIGTERM},
iterator::Signals,
low_level,
};
use clash_verge_logging::{Type, logging, logging_error};
use clash_verge_logging::{Type, logging};
use tokio::signal::unix::{SignalKind, signal};
use crate::RUNTIME;
@@ -15,39 +10,69 @@ where
{
if let Some(Some(rt)) = RUNTIME.get() {
rt.spawn(async move {
let signals = [SIGTERM, SIGINT, SIGHUP];
let mut sigs = match Signals::new(signals) {
let mut sigterm = match signal(SignalKind::terminate()) {
Ok(s) => s,
Err(e) => {
logging!(error, Type::System, "注册信号处理器失败: {}", e);
logging!(
error,
Type::SystemSignal,
"Failed to register SIGTERM: {}",
e
);
return;
}
};
let mut sigint = match signal(SignalKind::interrupt()) {
Ok(s) => s,
Err(e) => {
logging!(
error,
Type::SystemSignal,
"Failed to register SIGINT: {}",
e
);
return;
}
};
let mut sighup = match signal(SignalKind::hangup()) {
Ok(s) => s,
Err(e) => {
logging!(
error,
Type::SystemSignal,
"Failed to register SIGHUP: {}",
e
);
return;
}
};
for signal in &mut sigs {
let signal_to_str = |signal| match signal {
SIGTERM => "SIGTERM",
SIGINT => "SIGINT",
SIGHUP => "SIGHUP",
_ => "UNKNOWN",
};
loop {
let signal_name;
tokio::select! {
_ = sigterm.recv() => {
signal_name = "SIGTERM";
}
_ = sigint.recv() => {
signal_name = "SIGINT";
}
_ = sighup.recv() => {
signal_name = "SIGHUP";
}
else => {
break;
}
}
logging!(info, Type::System, "捕获到信号 {}", signal_to_str(signal));
logging!(info, Type::SystemSignal, "Caught signal {}", signal_name);
f().await;
logging_error!(
Type::System,
"信号 {:?} 默认处理失败",
low_level::emulate_default_handler(signal)
);
}
});
} else {
logging!(
error,
Type::System,
Type::SystemSignal,
"register shutdown signal failed, RUNTIME is not available"
);
}

View File

@@ -33,7 +33,7 @@ unsafe impl Sync for ShutdownState {}
impl Drop for ShutdownState {
fn drop(&mut self) {
// this log not be printed, I don't know why.
logging!(info, Type::System, "正在销毁系统关闭监听窗口");
logging!(info, Type::SystemSignal, "正在销毁系统关闭监听窗口");
unsafe {
DestroyWindow(self.hwnd);
}
@@ -52,7 +52,7 @@ unsafe extern "system" fn shutdown_proc(
WM_QUERYENDSESSION => {
logging!(
info,
Type::System,
Type::SystemSignal,
"System is shutting down or user is logging off."
);
}
@@ -60,21 +60,21 @@ unsafe extern "system" fn shutdown_proc(
if let Some(handler) = SHUTDOWN_HANDLER.get() {
if let Some(Some(rt)) = RUNTIME.get() {
rt.block_on(async {
logging!(info, Type::System, "Session ended, system shutting down.");
logging!(info, Type::SystemSignal, "Session ended, system shutting down.");
handler().await;
logging!(info, Type::System, "resolved reset finished");
logging!(info, Type::SystemSignal, "resolved reset finished");
});
} else {
logging!(
error,
Type::System,
Type::SystemSignal,
"handle shutdown signal failed, RUNTIME is not available"
);
}
} else {
logging!(
error,
Type::System,
Type::SystemSignal,
"WM_ENDSESSION received but no shutdown handler is registered"
);
}
@@ -105,6 +105,7 @@ fn get_instance_handle() -> windows_sys::Win32::Foundation::HMODULE {
unsafe { &__ImageBase as *const _ as _ }
}
//? 我们有机会采用类似 tokio 信号,不阻塞信号线程吗?
pub fn register<F, Fut>(app_handle: &AppHandle, f: F)
where
F: Fn() -> Fut + Send + Sync + 'static,
@@ -153,7 +154,7 @@ where
std::ptr::null_mut(),
);
if hwnd.is_null() {
logging!(error, Type::System, "failed to create shutdown window");
logging!(error, Type::SystemSignal, "failed to create shutdown window");
} else {
app_handle.manage(ShutdownState { hwnd });
}