From ba52debb5d2ce838fa17ba62919e1b8aa80e6516 Mon Sep 17 00:00:00 2001 From: Andy Gayton Date: Tue, 23 Jul 2024 16:57:53 -0400 Subject: [PATCH] mirror signals on EngineInterface --- crates/nu-plugin/src/plugin/interface/mod.rs | 11 +++++++++-- crates/nu-protocol/src/pipeline/signals.rs | 6 ++++++ crates/nu_plugin_example/src/commands/ctrlc.rs | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/nu-plugin/src/plugin/interface/mod.rs b/crates/nu-plugin/src/plugin/interface/mod.rs index e70a447321..8701e60680 100644 --- a/crates/nu-plugin/src/plugin/interface/mod.rs +++ b/crates/nu-plugin/src/plugin/interface/mod.rs @@ -18,7 +18,7 @@ use nu_protocol::{ use nu_utils::SharedCow; use std::{ collections::{btree_map, BTreeMap, HashMap}, - sync::{mpsc, Arc}, + sync::{atomic::AtomicBool, mpsc, Arc}, }; /// Plugin calls that are received by the [`EngineInterfaceManager`] for handling. @@ -64,6 +64,8 @@ struct EngineInterfaceState { mpsc::Sender<(EngineCallId, mpsc::Sender>)>, /// The synchronized output writer writer: Box>, + // Mirror signals from `EngineState` + signals: Signals, /// Registered Ctrl-C handlers ctrlc_handlers: ctrlc::Handlers, } @@ -119,6 +121,7 @@ impl EngineInterfaceManager { stream_id_sequence: Sequence::default(), engine_call_subscription_sender: subscription_tx, writer: Box::new(writer), + signals: Signals::new(Arc::new(AtomicBool::new(false))), ctrlc_handlers: ctrlc::Handlers::new(), }), protocol_info_mut, @@ -239,7 +242,6 @@ impl InterfaceManager for EngineInterfaceManager { fn consume(&mut self, input: Self::Input) -> Result<(), ShellError> { log::trace!("from engine: {:?}", input); - match input { PluginInput::Hello(info) => { let info = Arc::new(info); @@ -336,6 +338,7 @@ impl InterfaceManager for EngineInterfaceManager { self.send_engine_call_response(id, response) } PluginInput::Ctrlc => { + self.state.signals.trigger(); self.state.ctrlc_handlers.run(); Ok(()) } @@ -975,6 +978,10 @@ impl EngineInterface { self.write(PluginOutput::CallResponse(self.context()?, response))?; self.flush() } + + pub fn signals(&self) -> &Signals { + &self.state.signals + } } impl Interface for EngineInterface { diff --git a/crates/nu-protocol/src/pipeline/signals.rs b/crates/nu-protocol/src/pipeline/signals.rs index 06ce583c82..460efdf822 100644 --- a/crates/nu-protocol/src/pipeline/signals.rs +++ b/crates/nu-protocol/src/pipeline/signals.rs @@ -56,6 +56,12 @@ impl Signals { } } + pub fn trigger(&self) { + if let Some(signals) = &self.signals { + signals.store(true, Ordering::Relaxed); + } + } + /// Returns whether an interrupt has been triggered. #[inline] pub fn interrupted(&self) -> bool { diff --git a/crates/nu_plugin_example/src/commands/ctrlc.rs b/crates/nu_plugin_example/src/commands/ctrlc.rs index 5c46c848fc..32392f6136 100644 --- a/crates/nu_plugin_example/src/commands/ctrlc.rs +++ b/crates/nu_plugin_example/src/commands/ctrlc.rs @@ -41,6 +41,7 @@ impl PluginCommand for Ctrlc { eprintln!("waiting for ctrl-c signal..."); receiver.recv().expect("handler went away"); + eprintln!("interrupt status: {:?}", engine.signals().interrupted()); eprintln!("peace."); Ok(PipelineData::Empty)