Module nix::sys::timer

source ·
Available on crate feature time only.
Expand description

Timer API via signals.

Timer is a POSIX API to create timers and get expiration notifications through queued Unix signals, for the current process. This is similar to Linux’s timerfd mechanism, except that API is specific to Linux and makes use of file polling.

For more documentation, please read timer_create.

Examples

Create an interval timer that signals SIGALARM every 250 milliseconds.

use nix::sys::signal::{self, SigEvent, SigHandler, SigevNotify, Signal};
use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags};
use nix::time::ClockId;
use std::convert::TryFrom;
use std::sync::atomic::{AtomicU64, Ordering};
use std::thread::yield_now;
use std::time::Duration;

const SIG: Signal = Signal::SIGALRM;
static ALARMS: AtomicU64 = AtomicU64::new(0);

extern "C" fn handle_alarm(signal: libc::c_int) {
    let signal = Signal::try_from(signal).unwrap();
    if signal == SIG {
        ALARMS.fetch_add(1, Ordering::Relaxed);
    }
}

fn main() {
    let clockid = ClockId::CLOCK_MONOTONIC;
    let sigevent = SigEvent::new(SigevNotify::SigevSignal {
        signal: SIG,
        si_value: 0,
    });

    let mut timer = Timer::new(clockid, sigevent).unwrap();
    let expiration = Expiration::Interval(Duration::from_millis(250).into());
    let flags = TimerSetTimeFlags::empty();
    timer.set(expiration, flags).expect("could not set timer");

    let handler = SigHandler::Handler(handle_alarm);
    unsafe { signal::signal(SIG, handler) }.unwrap();

    loop {
        let alarms = ALARMS.load(Ordering::Relaxed);
        if alarms >= 10 {
            println!("total alarms handled: {}", alarms);
            break;
        }
        yield_now()
    }
}

Structs

A Unix signal per-process timer.
Flags that are used for arming the timer.

Enums

An enumeration allowing the definition of the expiration time of an alarm, recurring or not.