doc comments for the ctrlc module
This commit is contained in:
parent
915aa230c5
commit
5b2fc70fee
|
@ -3,11 +3,15 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::{engine::Sequence, ShellError};
|
use crate::{engine::Sequence, ShellError};
|
||||||
|
|
||||||
|
/// Handler is a closure that can be sent across threads and shared.
|
||||||
pub type Handler = Box<dyn Fn() + Send + Sync>;
|
pub type Handler = Box<dyn Fn() + Send + Sync>;
|
||||||
|
|
||||||
|
/// Manages a collection of handlers.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Handlers {
|
pub struct Handlers {
|
||||||
|
/// List of handler tuples containing an ID and the handler itself.
|
||||||
handlers: Arc<Mutex<Vec<(usize, Handler)>>>,
|
handlers: Arc<Mutex<Vec<(usize, Handler)>>>,
|
||||||
|
/// Sequence generator for unique IDs.
|
||||||
next_id: Arc<Sequence>,
|
next_id: Arc<Sequence>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,13 +23,17 @@ impl Debug for Handlers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Guard that unregisters a handler when dropped.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Guard {
|
pub struct Guard {
|
||||||
|
/// Unique ID of the handler.
|
||||||
id: usize,
|
id: usize,
|
||||||
|
/// Reference to the handlers list.
|
||||||
handlers: Arc<Mutex<Vec<(usize, Handler)>>>,
|
handlers: Arc<Mutex<Vec<(usize, Handler)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Guard {
|
impl Drop for Guard {
|
||||||
|
/// Drops the `Guard`, removing the associated handler from the list.
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Ok(mut handlers) = self.handlers.lock() {
|
if let Ok(mut handlers) = self.handlers.lock() {
|
||||||
handlers.retain(|(id, _)| *id != self.id);
|
handlers.retain(|(id, _)| *id != self.id);
|
||||||
|
@ -46,6 +54,8 @@ impl Handlers {
|
||||||
Handlers { handlers, next_id }
|
Handlers { handlers, next_id }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registers a new handler and returns an RAII guard which will unregister the handler when
|
||||||
|
/// dropped.
|
||||||
pub fn register(&self, handler: Handler) -> Result<Guard, ShellError> {
|
pub fn register(&self, handler: Handler) -> Result<Guard, ShellError> {
|
||||||
let id = self.next_id.next()?;
|
let id = self.next_id.next()?;
|
||||||
if let Ok(mut handlers) = self.handlers.lock() {
|
if let Ok(mut handlers) = self.handlers.lock() {
|
||||||
|
@ -57,6 +67,7 @@ impl Handlers {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Runs all registered handlers.
|
||||||
pub fn run(&self) {
|
pub fn run(&self) {
|
||||||
if let Ok(handlers) = self.handlers.lock() {
|
if let Ok(handlers) = self.handlers.lock() {
|
||||||
for (_, handler) in handlers.iter() {
|
for (_, handler) in handlers.iter() {
|
||||||
|
@ -78,6 +89,7 @@ mod tests {
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
/// Tests registering and running multiple handlers.
|
||||||
fn test_multiple_handlers() {
|
fn test_multiple_handlers() {
|
||||||
let handlers = Handlers::new();
|
let handlers = Handlers::new();
|
||||||
let called1 = Arc::new(AtomicBool::new(false));
|
let called1 = Arc::new(AtomicBool::new(false));
|
||||||
|
@ -100,6 +112,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
/// Tests the dropping of a guard and ensuring the handler is unregistered.
|
||||||
fn test_guard_drop() {
|
fn test_guard_drop() {
|
||||||
let handlers = Handlers::new();
|
let handlers = Handlers::new();
|
||||||
let called = Arc::new(AtomicBool::new(false));
|
let called = Arc::new(AtomicBool::new(false));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user