Expand description
Adapter of Linux’ signalfd
to be used with mio
0.7
use std::{thread, time::Duration};
use std::error::Error;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use mio::{Events, Interest, Poll, Token};
use pakr_signals::{Pid, Sig, SigSet};
use pakr_mio_signalfd::*;
const TOK: Token = Token(0);
fn main() -> Result<(), Box<dyn Error>> {
const SIGS: &[Sig] = &[Sig::USR2, Sig::USR1, Sig::QUIT];
// SigSet we are working with
let sigs = SigSet::from(SIGS);
// Make completion flags to be shared between threads
let done = Arc::new(AtomicBool::new(false));
let cdone = done.clone();
// Disable default hadlers of signals we play with
sigs.disable_default_handler()?;
// Spawn background thread that will (slowny) bomb our process with signals
let bomber = thread::spawn(move || {
// Get my own PID
let my_pid = Pid::own().unwrap();
// Repeat some times
for _ in 0..2 {
// For each signal on the list
for &sig in SIGS {
// Sleep a second
thread::sleep(Duration::from_secs(1));
println!("Sending {:?}", sig);
// ... then self-send signal
sig.send_to(my_pid).unwrap();
}
}
// Tell we're done
cdone.store(true, Ordering::Relaxed)
});
// Create a poll instance.
let mut poll = Poll::new()?;
// Create storage for events.
let mut events = Events::with_capacity(128);
// Create instance of signal watcher
let mut watcher = SignalFd::new(&sigs)?;
// Register watcher in mio registry. This handle is readable only
poll.registry().register(
&mut watcher,
TOK,
Interest::READABLE,
)?;
// Repeat while not told done
while !done.load(Ordering::Relaxed) {
// Poll Mio for events, blocking until we get an event or timeout on 3s.
poll.poll(&mut events, Some(Duration::from_secs(3)))?;
// Process each event.
for event in events.iter() {
// We can use the token we previously provided to `register` to
// determine for which socket the event is.
match event.token() {
TOK => {
println!("Handled event");
while let Some(siginfo) = watcher.read()? {
println!("Got signal {:?}", Sig::from(siginfo.ssi_signo as i32));
}
println!("---");
}
// We don't expect any events with tokens other than those we provided.
_ => { println!("Other event"); }
}
}
}
// Join with bomber thread
bomber.join().unwrap();
// Re-enable default handlers
sigs.enable_default_handler()?;
// We're done
Ok(())
}
Structs§
- Re-exported
libc::signalfd_siginfo
. SignalFd
can be used to create mio-compatible signal handlers.