refactor: reimplement the signal system (#1307)

This commit is contained in:
三咲雅 · Misaki Masa 2024-07-18 23:41:02 +08:00 committed by GitHub
parent f0cb365839
commit d6081fbe6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 138 additions and 113 deletions

71
Cargo.lock generated
View File

@ -258,9 +258,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.6.0"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
[[package]]
name = "cassowary"
@ -279,9 +279,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.100"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c891175c3fb232128f48de6590095e59198bbeb8620c310be349bfc3afd12c7b"
checksum = "47de7e88bbbd467951ae7f5a6f34f70d1b4d9cfce53d5fd70f74ebe118b3db56"
[[package]]
name = "cfg-if"
@ -361,7 +361,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -537,7 +537,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -548,7 +548,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
"darling_core",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -578,7 +578,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -588,7 +588,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
dependencies = [
"derive_builder_core",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -823,7 +823,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -1181,9 +1181,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.21"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "lru"
@ -1300,7 +1300,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -1417,9 +1417,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.36.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
dependencies = [
"memchr",
]
@ -1803,7 +1803,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -1936,7 +1936,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
dependencies = [
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -1970,7 +1970,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -1986,9 +1986,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.68"
version = "2.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
dependencies = [
"proc-macro2",
"quote",
@ -2033,7 +2033,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -2127,9 +2127,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.38.0"
version = "1.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
dependencies = [
"backtrace",
"bytes",
@ -2152,7 +2152,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -2181,9 +2181,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.8.14"
version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28"
dependencies = [
"indexmap",
"serde",
@ -2203,9 +2203,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.22.15"
version = "0.22.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
dependencies = [
"indexmap",
"serde",
@ -2245,7 +2245,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -2415,7 +2415,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -2506,7 +2506,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
"wasm-bindgen-shared",
]
@ -2528,7 +2528,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -2627,7 +2627,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -2638,7 +2638,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]
@ -2946,6 +2946,7 @@ dependencies = [
"syntect",
"tikv-jemallocator",
"tokio",
"tokio-stream",
"tokio-util",
"tracing",
"tracing-appender",
@ -3066,7 +3067,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
"syn 2.0.71",
]
[[package]]

View File

@ -1 +1 @@
{"flagWords":[],"version":"0.2","language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp"," Überzug"," Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes"]}
{"version":"0.2","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp"," Überzug"," Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP"],"language":"en","flagWords":[]}

View File

@ -25,7 +25,7 @@ imagesize = "0.13.0"
kamadak-exif = "0.5.5"
ratatui = "0.27.0"
scopeguard = "1.2.0"
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
# Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }

View File

@ -19,8 +19,8 @@ clap = { version = "4.5.9", features = [ "derive" ] }
crossterm = "0.27.0"
md-5 = "0.10.6"
serde_json = "1.0.120"
tokio = { version = "1.38.0", features = [ "full" ] }
toml_edit = "0.22.15"
tokio = { version = "1.38.1", features = [ "full" ] }
toml_edit = "0.22.16"
[build-dependencies]
anyhow = "1.0.86"

View File

@ -20,5 +20,5 @@ globset = "0.4.14"
indexmap = "2.2.6"
ratatui = "0.27.0"
serde = { version = "1.0.204", features = [ "derive" ] }
toml = { version = "0.8.14", features = [ "preserve_order" ] }
toml = { version = "0.8.15", features = [ "preserve_order" ] }
validator = { version = "0.18.1", features = [ "derive" ] }

View File

@ -31,7 +31,7 @@ regex = "1.10.5"
scopeguard = "1.2.0"
serde = "1.0.204"
shell-words = "1.1.0"
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
tokio-stream = "0.1.15"
tokio-util = "0.7.11"
unicode-width = "0.1.13"

View File

@ -5,9 +5,8 @@ use crate::manager::Manager;
impl Manager {
pub fn suspend(&mut self, _: Cmd) {
#[cfg(unix)]
tokio::spawn(async move {
yazi_proxy::AppProxy::stop().await;
unsafe { libc::raise(libc::SIGTSTP) };
});
unsafe {
libc::raise(libc::SIGTSTP);
}
}
}

View File

@ -22,7 +22,7 @@ mlua = { version = "0.9.9", features = [ "lua54" ] }
parking_lot = "0.12.3"
serde = { version = "1.0.204", features = [ "derive" ] }
serde_json = "1.0.120"
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
tokio-stream = "0.1.15"
tokio-util = "0.7.11"

View File

@ -32,7 +32,8 @@ mlua = { version = "0.9.9", features = [ "lua54" ] }
ratatui = "0.27.0"
scopeguard = "1.2.0"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
tokio-stream = "0.1.15"
tokio-util = "0.7.11"
# Logging

View File

@ -11,6 +11,6 @@ impl App {
// We need to trigger a resize, and render the UI based on the resized area.
self.resize(());
self.signals.resume();
self.signals.resume(None);
}
}

View File

@ -15,11 +15,7 @@ impl App {
pub(crate) fn stop(&mut self, opt: impl Into<Opt>) {
self.cx.manager.active_mut().preview.reset_image();
self.signals.stop();
self.signals.stop(opt.into().tx);
self.term = None;
if let Some(tx) = opt.into().tx {
tx.send(()).ok();
}
}
}

View File

@ -1,89 +1,117 @@
use anyhow::Result;
use crossterm::event::{Event as CrosstermEvent, EventStream, KeyEvent, KeyEventKind};
use futures::StreamExt;
use tokio::{select, task::JoinHandle};
use tokio_util::sync::CancellationToken;
use tokio::{select, sync::{mpsc, oneshot}};
use yazi_config::MANAGER;
use yazi_shared::event::Event;
pub(super) struct Signals {
ct: CancellationToken,
tx: mpsc::UnboundedSender<(bool, Option<oneshot::Sender<()>>)>,
}
impl Signals {
pub(super) fn start() -> Result<Self> {
let mut signals = Self { ct: CancellationToken::new() };
let (tx, rx) = mpsc::unbounded_channel();
Self::spawn(rx)?;
signals.spawn_system_task()?;
signals.spawn_crossterm_task();
Ok(signals)
Ok(Self { tx })
}
pub(super) fn stop(&mut self) {
if !self.ct.is_cancelled() {
self.ct.cancel();
}
pub(super) fn stop(&mut self, cb: Option<oneshot::Sender<()>>) { self.tx.send((false, cb)).ok(); }
pub(super) fn resume(&mut self, cb: Option<oneshot::Sender<()>>) {
self.tx.send((true, cb)).ok();
}
pub(super) fn resume(&mut self) {
if self.ct.is_cancelled() {
self.ct = CancellationToken::new();
self.spawn_crossterm_task();
#[cfg(unix)]
#[inline]
fn handle_sys(n: libc::c_int) -> bool {
use libc::{SIGCONT, SIGHUP, SIGQUIT, SIGSTOP, SIGTERM, SIGTSTP};
use tracing::error;
use yazi_proxy::{AppProxy, HIDER};
match n {
SIGHUP | SIGTERM | SIGQUIT => {
Event::Quit(Default::default()).emit();
return false;
}
SIGTSTP => {
tokio::spawn(async move {
AppProxy::stop().await;
if unsafe { libc::kill(0, SIGSTOP) } != 0 {
error!("Failed to stop the process:\n{}", std::io::Error::last_os_error());
Event::Quit(Default::default()).emit();
}
});
}
SIGCONT if HIDER.try_acquire().is_ok() => AppProxy::resume(),
_ => {}
}
true
}
#[cfg(windows)]
fn spawn_system_task(&self) -> Result<()> { Ok(()) }
#[inline]
fn handle_sys(_: ()) -> bool { unreachable!() }
#[cfg(unix)]
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGTERM};
use yazi_proxy::{AppProxy, HIDER};
let mut signals = signal_hook_tokio::Signals::new([
// Terminating signals
SIGHUP, SIGTERM, SIGQUIT, SIGINT, //
// Job control signals
SIGCONT,
])?;
Ok(tokio::spawn(async move {
while let Some(signal) = signals.next().await {
match signal {
SIGHUP | SIGTERM | SIGQUIT => {
Event::Quit(Default::default()).emit();
}
SIGCONT if HIDER.try_acquire().is_ok() => AppProxy::resume(),
_ => {}
#[inline]
fn handle_term(event: CrosstermEvent) {
match event {
CrosstermEvent::Key(key @ KeyEvent { kind: KeyEventKind::Press, .. }) => {
Event::Key(key).emit()
}
CrosstermEvent::Mouse(mouse) => {
if MANAGER.mouse_events.contains(mouse.kind.into()) {
Event::Mouse(mouse).emit();
}
}
}))
CrosstermEvent::Paste(str) => Event::Paste(str).emit(),
CrosstermEvent::Resize(..) => Event::Resize.emit(),
_ => {}
}
}
fn spawn_crossterm_task(&mut self) -> JoinHandle<()> {
let mut reader = EventStream::new();
let ct = self.ct.clone();
fn spawn(mut rx: mpsc::UnboundedReceiver<(bool, Option<oneshot::Sender<()>>)>) -> Result<()> {
#[cfg(unix)]
use libc::{SIGCONT, SIGHUP, SIGQUIT, SIGTERM, SIGTSTP};
#[cfg(unix)]
let mut sys = signal_hook_tokio::Signals::new([
// Terminating signals
SIGHUP, SIGTERM, SIGQUIT, //
// Job control signals
SIGTSTP, SIGCONT,
])?;
#[cfg(windows)]
let mut sys = tokio_stream::empty();
let mut term = Some(EventStream::new());
tokio::spawn(async move {
loop {
select! {
_ = ct.cancelled() => break,
Some(Ok(event)) = reader.next() => {
match event {
CrosstermEvent::Key(key @ KeyEvent { kind: KeyEventKind::Press, .. }) => Event::Key(key).emit(),
CrosstermEvent::Mouse(mouse) => {
if MANAGER.mouse_events.contains(mouse.kind.into()) {
Event::Mouse(mouse).emit();
}
},
CrosstermEvent::Paste(str) => Event::Paste(str).emit(),
CrosstermEvent::Resize(..) => Event::Resize.emit(),
_ => {},
}
if let Some(t) = &mut term {
select! {
biased;
Some(mut s) = rx.recv() => {
term = term.filter(|_| s.0);
s.1.take().map(|cb| cb.send(()));
},
Some(n) = sys.next() => if !Self::handle_sys(n) { return },
Some(Ok(e)) = t.next() => Self::handle_term(e)
}
} else {
select! {
biased;
Some(mut s) = rx.recv() => {
term = s.0.then(EventStream::new);
s.1.take().map(|cb| cb.send(()));
},
Some(n) = sys.next() => if !Self::handle_sys(n) { return },
}
}
}
})
});
Ok(())
}
}

View File

@ -33,7 +33,7 @@ ratatui = "0.27.0"
shell-escape = "0.1.5"
shell-words = "1.1.0"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
tokio-stream = "0.1.15"
tokio-util = "0.7.11"
unicode-width = "0.1.13"

View File

@ -19,4 +19,4 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
# External dependencies
anyhow = "1.0.86"
mlua = { version = "0.9.9", features = [ "lua54" ] }
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }

View File

@ -21,7 +21,7 @@ async-priority-channel = "0.2.0"
futures = "0.3.30"
parking_lot = "0.12.3"
scopeguard = "1.2.0"
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
# Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }

View File

@ -21,7 +21,7 @@ ratatui = "0.27.0"
regex = "1.10.5"
serde = { version = "1.0.204", features = [ "derive" ] }
shell-words = "1.1.0"
tokio = { version = "1.38.0", features = [ "full" ] }
tokio = { version = "1.38.1", features = [ "full" ] }
[target."cfg(unix)".dependencies]
libc = "0.2.155"