diff --git a/Cargo.lock b/Cargo.lock index 59b70408..834d271c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -704,6 +704,7 @@ dependencies = [ "jay-geometry", "jay-io-uring", "jay-layout-animation", + "jay-sighand", "jay-time", "jay-toml-config", "jay-tracy", @@ -856,6 +857,18 @@ dependencies = [ "jay-geometry", ] +[[package]] +name = "jay-sighand" +version = "0.1.0" +dependencies = [ + "jay-async-engine", + "jay-io-uring", + "jay-utils", + "log", + "thiserror", + "uapi", +] + [[package]] name = "jay-time" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0bf04b70..8b89a004 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ members = [ "eventfd-cache", "wheel", "cpu-worker", + "sighand", "toml-config", "algorithms", "toml-spec", @@ -77,6 +78,7 @@ jay-tree-types = { version = "0.1.0", path = "tree-types" } jay-eventfd-cache = { version = "0.1.0", path = "eventfd-cache" } jay-wheel = { version = "0.1.0", path = "wheel" } jay-cpu-worker = { version = "0.1.0", path = "cpu-worker" } +jay-sighand = { version = "0.1.0", path = "sighand" } uapi = "0.2.13" thiserror = "2.0.11" diff --git a/sighand/Cargo.toml b/sighand/Cargo.toml new file mode 100644 index 00000000..52fde7f3 --- /dev/null +++ b/sighand/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "jay-sighand" +version = "0.1.0" +edition = "2024" +license = "GPL-3.0-only" + +[dependencies] +jay-async-engine = { version = "0.1.0", path = "../async-engine" } +jay-io-uring = { version = "0.1.0", path = "../io-uring" } +jay-utils = { version = "0.1.0", path = "../utils" } + +log = { version = "0.4.20", features = ["std"] } +thiserror = "2.0.11" +uapi = "0.2.13" diff --git a/sighand/src/lib.rs b/sighand/src/lib.rs new file mode 100644 index 00000000..f58d46df --- /dev/null +++ b/sighand/src/lib.rs @@ -0,0 +1,63 @@ +use { + jay_async_engine::{AsyncEngine, SpawnedFuture}, + jay_io_uring::IoUring, + jay_utils::{ + buf::TypedBuf, + errorfmt::ErrorFmt, + oserror::{OsError, OsErrorExt2}, + }, + std::rc::Rc, + thiserror::Error, + uapi::{OwnedFd, c}, +}; + +#[derive(Debug, Error)] +pub enum SighandError { + #[error("Could not block the signalfd signals")] + BlockFailed(#[source] OsError), + #[error("Could not create a signalfd")] + CreateFailed(#[source] OsError), +} + +pub fn install( + eng: &Rc, + ring: &Rc, +) -> Result, SighandError> { + let mut set: c::sigset_t = uapi::pod_zeroed(); + uapi::sigaddset(&mut set, c::SIGINT).unwrap(); + uapi::sigaddset(&mut set, c::SIGTERM).unwrap(); + uapi::sigaddset(&mut set, c::SIGPIPE).unwrap(); + uapi::pthread_sigmask(c::SIG_BLOCK, Some(&set), None).map_os_err(SighandError::BlockFailed)?; + let fd = uapi::signalfd_new(&set, c::SFD_CLOEXEC) + .map(Rc::new) + .map_os_err(SighandError::CreateFailed)?; + Ok(eng.spawn("signal handler", handle_signals(fd, ring.clone()))) +} + +async fn handle_signals(fd: Rc, ring: Rc) { + let mut buf = TypedBuf::::new(); + loop { + if let Err(e) = ring.read(&fd, buf.buf()).await { + log::error!("Could not read from signal fd: {}", ErrorFmt(e)); + return; + } + let sig = buf.t().ssi_signo as i32; + log::info!("Received signal {}", sig); + if matches!(sig, c::SIGINT | c::SIGTERM) { + log::info!("Exiting"); + ring.stop(); + } + } +} + +pub fn reset_all() { + const NSIG: c::c_int = 64; + unsafe { + for sig in 1..=NSIG { + c::signal(sig, c::SIG_DFL); + } + } + let mut set: c::sigset_t = uapi::pod_zeroed(); + uapi::sigfillset(&mut set).unwrap(); + let _ = uapi::pthread_sigmask(c::SIG_UNBLOCK, Some(&set), None); +} diff --git a/src/sighand.rs b/src/sighand.rs index 484a9145..47d33d33 100644 --- a/src/sighand.rs +++ b/src/sighand.rs @@ -1,65 +1 @@ -use { - crate::{ - async_engine::{AsyncEngine, SpawnedFuture}, - io_uring::IoUring, - utils::{ - buf::TypedBuf, - errorfmt::ErrorFmt, - oserror::{OsError, OsErrorExt2}, - }, - }, - std::rc::Rc, - thiserror::Error, - uapi::{OwnedFd, c}, -}; - -#[derive(Debug, Error)] -pub enum SighandError { - #[error("Could not block the signalfd signals")] - BlockFailed(#[source] OsError), - #[error("Could not create a signalfd")] - CreateFailed(#[source] OsError), -} - -pub fn install( - eng: &Rc, - ring: &Rc, -) -> Result, SighandError> { - let mut set: c::sigset_t = uapi::pod_zeroed(); - uapi::sigaddset(&mut set, c::SIGINT).unwrap(); - uapi::sigaddset(&mut set, c::SIGTERM).unwrap(); - uapi::sigaddset(&mut set, c::SIGPIPE).unwrap(); - uapi::pthread_sigmask(c::SIG_BLOCK, Some(&set), None).map_os_err(SighandError::BlockFailed)?; - let fd = uapi::signalfd_new(&set, c::SFD_CLOEXEC) - .map(Rc::new) - .map_os_err(SighandError::CreateFailed)?; - Ok(eng.spawn("signal handler", handle_signals(fd, ring.clone()))) -} - -async fn handle_signals(fd: Rc, ring: Rc) { - let mut buf = TypedBuf::::new(); - loop { - if let Err(e) = ring.read(&fd, buf.buf()).await { - log::error!("Could not read from signal fd: {}", ErrorFmt(e)); - return; - } - let sig = buf.t().ssi_signo as i32; - log::info!("Received signal {}", sig); - if matches!(sig, c::SIGINT | c::SIGTERM) { - log::info!("Exiting"); - ring.stop(); - } - } -} - -pub fn reset_all() { - const NSIG: c::c_int = 64; - unsafe { - for sig in 1..=NSIG { - c::signal(sig, c::SIG_DFL); - } - } - let mut set: c::sigset_t = uapi::pod_zeroed(); - uapi::sigfillset(&mut set).unwrap(); - let _ = uapi::pthread_sigmask(c::SIG_UNBLOCK, Some(&set), None); -} +pub use jay_sighand::*;