#![cfg(unix)]
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
#[derive(Debug, Clone, Default)]
pub struct SignalFlags {
pub sigusr1: Arc<AtomicBool>,
pub sigwinch: Arc<AtomicBool>,
}
impl SignalFlags {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn take_sigusr1(&self) -> bool {
self.sigusr1.swap(false, Ordering::AcqRel)
}
pub fn take_sigwinch(&self) -> bool {
self.sigwinch.swap(false, Ordering::AcqRel)
}
}
pub fn register(flags: &SignalFlags) -> Result<Registration, std::io::Error> {
use signal_hook::consts::{SIGUSR1, SIGWINCH};
use signal_hook::flag;
let sigusr1_id = flag::register(SIGUSR1, flags.sigusr1.clone())?;
let sigwinch_id = flag::register(SIGWINCH, flags.sigwinch.clone())?;
Ok(Registration {
_sigusr1: sigusr1_id,
_sigwinch: sigwinch_id,
})
}
#[derive(Debug)]
pub struct Registration {
_sigusr1: signal_hook::SigId,
_sigwinch: signal_hook::SigId,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn flags_round_trip() {
let f = SignalFlags::new();
assert!(!f.take_sigusr1());
assert!(!f.take_sigwinch());
f.sigusr1.store(true, Ordering::Release);
f.sigwinch.store(true, Ordering::Release);
assert!(f.take_sigusr1());
assert!(f.take_sigwinch());
assert!(!f.take_sigusr1());
assert!(!f.take_sigwinch());
}
}