[][src]Crate pakr_mio_signalfd

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

    // 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

                println!("Sending {:?}", sig);

                //  ... then self-send signal
        // 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
        &mut watcher,

    // 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));

                // We don't expect any events with tokens other than those we provided.
                _ => { println!("Other event"); }

    // Join with bomber thread

    // Re-enable default handlers

    // We're done



Re-exported libc::signalfd_siginfo.


SignalFd can be used to create mio-compatible signal handlers.