From 1060b65e14c1abdde71e5bce8bbe90b989a2911d Mon Sep 17 00:00:00 2001 From: Andy Gayton Date: Thu, 4 Jul 2024 20:47:10 -0400 Subject: [PATCH] wip --- crates/nu-plugin-engine/src/persistent.rs | 13 +++++++++++-- crates/nu-protocol/src/engine/ctrlc.rs | 1 + crates/nu-protocol/src/engine/engine_state.rs | 10 ++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/crates/nu-plugin-engine/src/persistent.rs b/crates/nu-plugin-engine/src/persistent.rs index b496174d91..5998c96f44 100644 --- a/crates/nu-plugin-engine/src/persistent.rs +++ b/crates/nu-plugin-engine/src/persistent.rs @@ -299,14 +299,23 @@ impl RegisteredPlugin for PersistentPlugin { } } + fn as_any(self: Arc) -> Arc { + self + } + fn set_ctrlc_handler_guard(&self, guard: ctrlc::Guard) { if let Ok(mut mutable) = self.mutable.lock() { mutable.ctrlc_guard = Some(guard); } } - fn as_any(self: Arc) -> Arc { - self + fn ctrlc(&self) -> Result<(), ShellError> { + if let Ok(mutable) = self.mutable.lock() { + if let Some(ref running) = mutable.running { + return running.interface.ctrlc(); + } + } + Ok(()) } } diff --git a/crates/nu-protocol/src/engine/ctrlc.rs b/crates/nu-protocol/src/engine/ctrlc.rs index 3d48495373..11121f7c9c 100644 --- a/crates/nu-protocol/src/engine/ctrlc.rs +++ b/crates/nu-protocol/src/engine/ctrlc.rs @@ -61,6 +61,7 @@ impl Handlers { if let Ok(mut handlers) = self.handlers.lock() { handlers.push((id, handler)); } + Ok(Guard { id, handlers: Arc::clone(&self.handlers), diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 772c976bf1..e5d64ee3d5 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -262,9 +262,15 @@ impl EngineState { for plugin in std::mem::take(&mut delta.plugins) { if let Some(handlers) = self.ctrlc_handlers.as_ref() { let guard = { - let plugin = plugin.clone(); + // We take a weakref to the plugin so that we don't create a cycle to the + // RAII guard that will be stored on the plugin. + let plugin = Arc::downgrade(&plugin); handlers.register(Box::new(move || { - let _ = plugin.ctrlc(); + // If the plugin is still alive, call its ctrlc handler. It should + // never be None because the guard is dropped when the plugin is. + if let Some(plugin) = plugin.upgrade() { + let _ = plugin.ctrlc(); + } }))? }; plugin.set_ctrlc_handler_guard(guard);