mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 07:14:40 +08:00
refactor(signal): migrate signal to handling async in unix and remove signal-hook dependency
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
- 优化应用重启/退出时的资源清理性能, 大幅缩短执行时间
|
||||
- 优化 WebSocket 连接机制
|
||||
- 改进旧版 Service 需要重新安装检测流程
|
||||
- 优化 macOS 和 Linux 信号处理
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
@@ -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]"),
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -19,7 +19,7 @@ where
|
||||
Err(e) => {
|
||||
logging!(
|
||||
info,
|
||||
Type::System,
|
||||
Type::SystemSignal,
|
||||
"register shutdown signal failed, create tokio runtime error: {}",
|
||||
e
|
||||
);
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user