update ctrlc Handlers to use Sequence
This commit is contained in:
parent
c3dee0fef1
commit
dbddf3e7fd
|
@ -217,12 +217,14 @@ impl PersistentPlugin {
|
||||||
return self.spawn(envs, mutable, ctrlc_handlers);
|
return self.spawn(envs, mutable, ctrlc_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
let guard = ctrlc_handlers.map(|ctrlc_handlers| {
|
let guard = ctrlc_handlers
|
||||||
|
.map(|ctrlc_handlers| {
|
||||||
let interface = interface.clone();
|
let interface = interface.clone();
|
||||||
ctrlc_handlers.register(Box::new(move || {
|
ctrlc_handlers.register(Box::new(move || {
|
||||||
let _ = interface.ctrlc();
|
let _ = interface.ctrlc();
|
||||||
}))
|
}))
|
||||||
});
|
})
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
mutable.running = Some(RunningPlugin {
|
mutable.running = Some(RunningPlugin {
|
||||||
interface,
|
interface,
|
||||||
|
|
|
@ -517,7 +517,10 @@ impl EngineInterface {
|
||||||
|
|
||||||
/// Register a closure which will be called when the engine receives a Ctrl-C signal. Returns a
|
/// Register a closure which will be called when the engine receives a Ctrl-C signal. Returns a
|
||||||
/// RAII guard that will keep the closure alive until it is dropped.
|
/// RAII guard that will keep the closure alive until it is dropped.
|
||||||
pub fn register_ctrlc_handler(&self, handler: ctrlc::Handler) -> ctrlc::Guard {
|
pub fn register_ctrlc_handler(
|
||||||
|
&self,
|
||||||
|
handler: ctrlc::Handler,
|
||||||
|
) -> Result<ctrlc::Guard, ShellError> {
|
||||||
self.state.ctrlc_handlers.register(handler)
|
self.state.ctrlc_handlers.register(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::{
|
use std::sync::{Arc, Mutex};
|
||||||
atomic::{AtomicU64, Ordering},
|
|
||||||
Arc, Mutex,
|
use crate::{engine::Sequence, ShellError};
|
||||||
};
|
|
||||||
|
|
||||||
pub type Handler = Box<dyn Fn() + Send + Sync>;
|
pub type Handler = Box<dyn Fn() + Send + Sync>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Handlers {
|
pub struct Handlers {
|
||||||
handlers: Arc<Mutex<Vec<(u64, Handler)>>>,
|
handlers: Arc<Mutex<Vec<(usize, Handler)>>>,
|
||||||
// we use an u64 so an overflow is impractical
|
next_id: Arc<Sequence>,
|
||||||
next_id: Arc<AtomicU64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Guard {
|
pub struct Guard {
|
||||||
id: u64,
|
id: usize,
|
||||||
handlers: Arc<Mutex<Vec<(u64, Handler)>>>,
|
handlers: Arc<Mutex<Vec<(usize, Handler)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Guard {
|
impl Drop for Guard {
|
||||||
|
@ -36,19 +34,19 @@ impl Debug for Guard {
|
||||||
impl Handlers {
|
impl Handlers {
|
||||||
pub fn new() -> Handlers {
|
pub fn new() -> Handlers {
|
||||||
let handlers = Arc::new(Mutex::new(vec![]));
|
let handlers = Arc::new(Mutex::new(vec![]));
|
||||||
let next_id = Arc::new(AtomicU64::new(0));
|
let next_id = Arc::new(Sequence::default());
|
||||||
Handlers { handlers, next_id }
|
Handlers { handlers, next_id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register(&self, handler: Handler) -> Guard {
|
pub fn register(&self, handler: Handler) -> Result<Guard, ShellError> {
|
||||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
let id = self.next_id.next()?;
|
||||||
if let Ok(mut handlers) = self.handlers.lock() {
|
if let Ok(mut handlers) = self.handlers.lock() {
|
||||||
handlers.push((id, handler));
|
handlers.push((id, handler));
|
||||||
}
|
}
|
||||||
Guard {
|
Ok(Guard {
|
||||||
id,
|
id,
|
||||||
handlers: Arc::clone(&self.handlers),
|
handlers: Arc::clone(&self.handlers),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self) {
|
pub fn run(&self) {
|
||||||
|
@ -69,7 +67,7 @@ impl Default for Handlers {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_multiple_handlers() {
|
fn test_multiple_handlers() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user