From 469d1abca55d3d9a85e2c1a72aa20c81f98f9b16 Mon Sep 17 00:00:00 2001 From: Andy Gayton Date: Wed, 19 Jun 2024 11:29:21 -0400 Subject: [PATCH] sketch what adding a broadcast bus to engine_state looks like --- Cargo.lock | 13 +++++++++++++ Cargo.toml | 1 + crates/nu-protocol/Cargo.toml | 1 + crates/nu-protocol/src/engine/engine_state.rs | 2 ++ src/main.rs | 5 +++-- src/signals.rs | 16 ++++++++++++---- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0db346b785..bb4a18f890 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -516,6 +516,17 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "bus" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b7118d0221d84fada881b657c2ddb7cd55108db79c8764c9ee212c0c259b783" +dependencies = [ + "crossbeam-channel", + "num_cpus", + "parking_lot_core", +] + [[package]] name = "byte-unit" version = "5.1.4" @@ -2765,6 +2776,7 @@ name = "nu" version = "0.94.3" dependencies = [ "assert_cmd", + "bus", "crossterm", "ctrlc", "dirs-next", @@ -3226,6 +3238,7 @@ name = "nu-protocol" version = "0.94.3" dependencies = [ "brotli", + "bus", "byte-unit", "chrono", "chrono-humanize", diff --git a/Cargo.toml b/Cargo.toml index 18f45987e7..6c55071633 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -208,6 +208,7 @@ mimalloc = { version = "0.1.42", default-features = false, optional = true } serde_json = { workspace = true } simplelog = "0.12" time = "0.3" +bus = "2.4.1" [target.'cfg(not(target_os = "windows"))'.dependencies] # Our dependencies don't use OpenSSL on Windows diff --git a/crates/nu-protocol/Cargo.toml b/crates/nu-protocol/Cargo.toml index 849a968eb8..2c09ebf52f 100644 --- a/crates/nu-protocol/Cargo.toml +++ b/crates/nu-protocol/Cargo.toml @@ -33,6 +33,7 @@ serde = { workspace = true, default-features = false } thiserror = "1.0" typetag = "0.2" os_pipe = { workspace = true, features = ["io_safety"] } +bus = "2.4.1" [target.'cfg(unix)'.dependencies] nix = { workspace = true, default-features = false, features = ["signal"] } diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 3960f6d9d0..d922330060 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -85,6 +85,7 @@ pub struct EngineState { usage: Usage, pub scope: ScopeFrame, pub ctrlc: Option>, + pub ctrlc_bus: Option>>>, pub env_vars: Arc, pub previous_env_vars: Arc>, pub config: Arc, @@ -145,6 +146,7 @@ impl EngineState { false, ), ctrlc: None, + ctrlc_bus: None, env_vars: Arc::new( [(DEFAULT_OVERLAY_NAME.to_string(), HashMap::new())] .into_iter() diff --git a/src/main.rs b/src/main.rs index 41d5534bb0..72868e8095 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,7 +35,7 @@ use signals::ctrlc_protection; use std::{ path::PathBuf, str::FromStr, - sync::{atomic::AtomicBool, Arc}, + sync::{atomic::AtomicBool, Mutex, Arc}, }; fn get_engine_state() -> EngineState { @@ -75,8 +75,9 @@ fn main() -> Result<()> { } let ctrlc = Arc::new(AtomicBool::new(false)); + let ctrlc_bus = Arc::new(Mutex::new(bus::Bus::new(1))); // TODO: make this conditional in the future - ctrlc_protection(&mut engine_state, &ctrlc); + ctrlc_protection(&mut engine_state, &ctrlc, &ctrlc_bus); // Begin: Default NU_LIB_DIRS, NU_PLUGIN_DIRS // Set default NU_LIB_DIRS and NU_PLUGIN_DIRS here before the env.nu is processed. If diff --git a/src/signals.rs b/src/signals.rs index 9247ccb095..2ef3b632c9 100644 --- a/src/signals.rs +++ b/src/signals.rs @@ -1,17 +1,25 @@ use nu_protocol::engine::EngineState; use std::sync::{ atomic::{AtomicBool, Ordering}, - Arc, + Arc, Mutex, }; -pub(crate) fn ctrlc_protection(engine_state: &mut EngineState, ctrlc: &Arc) { +pub(crate) fn ctrlc_protection( + engine_state: &mut EngineState, + ctrlc: &Arc, + tx: &Arc>>, +) { let handler_ctrlc = ctrlc.clone(); - let engine_state_ctrlc = ctrlc.clone(); + let handler_tx = tx.clone(); ctrlc::set_handler(move || { handler_ctrlc.store(true, Ordering::SeqCst); + if let Ok(mut bus) = handler_tx.lock() { + let _ = bus.try_broadcast(()); + } }) .expect("Error setting Ctrl-C handler"); - engine_state.ctrlc = Some(engine_state_ctrlc); + engine_state.ctrlc = Some(ctrlc.clone()); + engine_state.ctrlc_bus = Some(tx.clone()); }