From a6e7c3e3d6b91e5aa3c37e2a4b79edf31e445aa2 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sat, 19 Mar 2022 11:53:43 +0800 Subject: [PATCH] Fix suspend when running hx within git When editing git commit message using helix, when ctrl-z is pressed the terminal will get stuck since helix does not suspend correctly, as helix is currently using tokio with multi-threads, with signal-hook default low_level::emulate_default_handler it only send the SIGSTOP to the current process but tokio uses multi-process so not everything gets suspended and the terminal also gets stuck. Now switched to use libc kill function and send it to pid 0 so that all processes gets suspended correctly. --- Cargo.lock | 23 +++++++++++++++++++++++ helix-term/Cargo.toml | 1 + helix-term/src/application.rs | 17 ++++++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa17698cc79b..95e158c7fc04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -451,6 +451,7 @@ dependencies = [ "helix-view", "ignore", "log", + "nix", "num_cpus", "once_cell", "pulldown-cmark", @@ -634,6 +635,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "mio" version = "0.7.14" @@ -670,6 +680,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "nix" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "ntapi" version = "0.3.7" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 4f869b62aced..b579f0dcaf9b 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -67,6 +67,7 @@ grep-searcher = "0.1.8" # Remove once retain_mut lands in stable rust retain_mut = "0.1.7" +nix = "0.23" [target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 269ce13d15a8..007f88c7723a 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -31,10 +31,7 @@ use crossterm::{ tty::IsTty, }; #[cfg(not(windows))] -use { - signal_hook::{consts::signal, low_level}, - signal_hook_tokio::Signals, -}; +use {signal_hook::consts::signal, signal_hook_tokio::Signals}; #[cfg(windows)] type Signals = futures_util::stream::Empty<()>; @@ -254,9 +251,19 @@ impl Application { use helix_view::graphics::Rect; match signal { signal::SIGTSTP => { + use nix::{ + sys::signal::{self, Signal}, + unistd::Pid, + }; self.compositor.save_cursor(); self.restore_term().unwrap(); - low_level::emulate_default_handler(signal::SIGTSTP).unwrap(); + // low_level::emulate_default_handler(signal::SIGSTSP) only + // send SIGSTOP to the current process but since we use + // multi-process tokio, at times like using helix within + // git suspend will not work since only the current process + // is suspended, so we had to send SIGSTOP signal to the + // whole process to make sure it is suspended correctly. + signal::kill(Pid::from_raw(0), Signal::SIGSTOP).unwrap(); } signal::SIGCONT => { self.claim_term().await.unwrap();