From f3ba35888ef78fc87080fc958adc3abfa5183d52 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 19 Feb 2024 14:09:58 +0100 Subject: [PATCH] feat: handle more POSIX signals on UNIX systems Signed-off-by: ljedrz --- node/src/traits.rs | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/node/src/traits.rs b/node/src/traits.rs index 12947ca3f2..e543247261 100644 --- a/node/src/traits.rs +++ b/node/src/traits.rs @@ -17,6 +17,8 @@ use snarkvm::prelude::{Address, Network, PrivateKey, ViewKey}; use once_cell::sync::OnceCell; use std::{ + future::Future, + io, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -53,15 +55,45 @@ pub trait NodeInterface: Routing { /// Handles OS signals for the node to intercept and perform a clean shutdown. /// The optional `shutdown_flag` flag can be used to cleanly terminate the syncing process. - /// Note: Only Ctrl-C is supported; it should work on both Unix-family systems and Windows. fn handle_signals(shutdown_flag: Arc) -> Arc> { // In order for the signal handler to be started as early as possible, a reference to the node needs // to be passed to it at a later time. let node: Arc> = Default::default(); + #[cfg(target_family = "unix")] + fn signal_listener() -> impl Future> { + use tokio::signal::unix::{signal, SignalKind}; + + async { + tokio::select!( + _ = async { + let mut s_int = signal(SignalKind::interrupt()).unwrap(); + s_int.recv().await; + } => (), + _ = async { + let mut s_term = signal(SignalKind::terminate()).unwrap(); + s_term.recv().await; + } => (), + _ = async { + let mut s_quit = signal(SignalKind::quit()).unwrap(); + s_quit.recv().await; + } => (), + _ = async { + let mut s_hup = signal(SignalKind::hangup()).unwrap(); + s_hup.recv().await; + } => (), + ); + Ok(()) + } + } + #[cfg(not(target_family = "unix"))] + fn signal_listener() -> impl Future> { + tokio::signal::ctrl_c() + } + let node_clone = node.clone(); tokio::task::spawn(async move { - match tokio::signal::ctrl_c().await { + match signal_listener().await { Ok(()) => { match node_clone.get() { // If the node is already initialized, then shut it down.