use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, }; use tokio::{ self, signal, sync::{futures::Notified, Notify}, }; pub struct ExitListener { should_exit: Arc, notify: Arc, } impl ExitListener { pub fn new() -> Self { let this = Self { should_exit: Arc::new(AtomicBool::new(false)), notify: Arc::new(Notify::new()), }; let should_exit = this.should_exit.clone(); let notify = this.notify.clone(); tokio::spawn(async move { signal::ctrl_c() .await .expect("Failed to install CTRL+C signal handler"); should_exit.store(true, Ordering::SeqCst); notify.notify_one(); }); this } pub fn notified(&self) -> Notified<'_> { self.notify.notified() } pub fn should_exit(&self) -> bool { self.should_exit.load(Ordering::SeqCst) } }