Add and use new Signals struct (#13314)

# Description
This PR introduces a new `Signals` struct to replace our adhoc passing
around of `ctrlc: Option<Arc<AtomicBool>>`. Doing so has a few benefits:
- We can better enforce when/where resetting or triggering an interrupt
is allowed.
- Consolidates `nu_utils::ctrl_c::was_pressed` and other ad-hoc
re-implementations into a single place: `Signals::check`.
- This allows us to add other types of signals later if we want. E.g.,
exiting or suspension.
- Similarly, we can more easily change the underlying implementation if
we need to in the future.
- Places that used to have a `ctrlc` of `None` now use
`Signals::empty()`, so we can double check these usages for correctness
in the future.
This commit is contained in:
Ian Manske
2024-07-07 22:29:01 +00:00
committed by GitHub
parent c6b6b1b7a8
commit 399a7c8836
246 changed files with 1332 additions and 1234 deletions

View File

@ -3,23 +3,21 @@ use nu_engine::{get_eval_block_with_early_return, get_full_help, ClosureEvalOnce
use nu_protocol::{
ast::Call,
engine::{Closure, EngineState, Redirection, Stack},
Config, IntoSpanned, OutDest, PipelineData, PluginIdentity, ShellError, Span, Spanned, Value,
Config, IntoSpanned, OutDest, PipelineData, PluginIdentity, ShellError, Signals, Span, Spanned,
Value,
};
use std::{
borrow::Cow,
collections::HashMap,
sync::{
atomic::{AtomicBool, AtomicU32},
Arc,
},
sync::{atomic::AtomicU32, Arc},
};
/// Object safe trait for abstracting operations required of the plugin context.
pub trait PluginExecutionContext: Send + Sync {
/// A span pointing to the command being executed
fn span(&self) -> Span;
/// The interrupt signal, if present
fn ctrlc(&self) -> Option<&Arc<AtomicBool>>;
/// The [`Signals`] struct, if present
fn signals(&self) -> &Signals;
/// The pipeline externals state, for tracking the foreground process group, if present
fn pipeline_externals_state(&self) -> Option<&Arc<(AtomicU32, AtomicU32)>>;
/// Get engine configuration
@ -80,8 +78,8 @@ impl<'a> PluginExecutionContext for PluginExecutionCommandContext<'a> {
self.call.head
}
fn ctrlc(&self) -> Option<&Arc<AtomicBool>> {
self.engine_state.ctrlc.as_ref()
fn signals(&self) -> &Signals {
self.engine_state.signals()
}
fn pipeline_externals_state(&self) -> Option<&Arc<(AtomicU32, AtomicU32)>> {
@ -234,8 +232,8 @@ impl PluginExecutionContext for PluginExecutionBogusContext {
Span::test_data()
}
fn ctrlc(&self) -> Option<&Arc<AtomicBool>> {
None
fn signals(&self) -> &Signals {
&Signals::EMPTY
}
fn pipeline_externals_state(&self) -> Option<&Arc<(AtomicU32, AtomicU32)>> {