Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  test_timer.rs   Sprache: unbekannt

 
use nix::sys::signal::{
    sigaction, SaFlags, SigAction, SigEvent, SigHandler, SigSet, SigevNotify,
    Signal,
};
use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags};
use nix::time::ClockId;
use std::convert::TryFrom;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::time::{Duration, Instant};

const SIG: Signal = Signal::SIGALRM;
static ALARM_CALLED: AtomicBool = AtomicBool::new(false);

pub extern "C" fn handle_sigalarm(raw_signal: libc::c_int) {
    let signal = Signal::try_from(raw_signal).unwrap();
    if signal == SIG {
        ALARM_CALLED.store(true, Ordering::Release);
    }
}

#[test]
fn alarm_fires() {
    // Avoid interfering with other signal using tests by taking a mutex shared
    // among other tests in this crate.
    let _m = crate::SIGNAL_MTX.lock();
    const TIMER_PERIOD: Duration = Duration::from_millis(100);

    //
    // Setup
    //

    // Create a handler for the test signal, `SIG`. The handler is responsible
    // for flipping `ALARM_CALLED`.
    let handler = SigHandler::Handler(handle_sigalarm);
    let signal_action =
        SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty());
    let old_handler = unsafe {
        sigaction(SIG, &signal_action)
            .expect("unable to set signal handler for alarm")
    };

    // Create the timer. We use the monotonic clock here, though any would do
    // really. The timer is set to fire every 250 milliseconds with no delay for
    // the initial firing.
    let clockid = ClockId::CLOCK_MONOTONIC;
    let sigevent = SigEvent::new(SigevNotify::SigevSignal {
        signal: SIG,
        si_value: 0,
    });
    let mut timer =
        Timer::new(clockid, sigevent).expect("failed to create timer");
    let expiration = Expiration::Interval(TIMER_PERIOD.into());
    let flags = TimerSetTimeFlags::empty();
    timer.set(expiration, flags).expect("could not set timer");

    //
    // Test
    //

    // Determine that there's still an expiration tracked by the
    // timer. Depending on when this runs either an `Expiration::Interval` or
    // `Expiration::IntervalDelayed` will be present. That is, if the timer has
    // not fired yet we'll get our original `expiration`, else the one that
    // represents a delay to the next expiration. We're only interested in the
    // timer still being extant.
    match timer.get() {
        Ok(Some(exp)) => assert!(matches!(
            exp,
            Expiration::Interval(..) | Expiration::IntervalDelayed(..)
        )),
        _ => panic!("timer lost its expiration"),
    }

    // Wait for 2 firings of the alarm before checking that it has fired and
    // been handled at least the once. If we wait for 3 seconds and the handler
    // is never called something has gone sideways and the test fails.
    let starttime = Instant::now();
    loop {
        thread::sleep(2 * TIMER_PERIOD);
        if ALARM_CALLED.load(Ordering::Acquire) {
            break;
        }
        if starttime.elapsed() > Duration::from_secs(3) {
            panic!("Timeout waiting for SIGALRM");
        }
    }

    // Cleanup:
    // 1) deregister the OS's timer.
    // 2) Wait for a full timer period, since POSIX does not require that
    //    disabling the timer will clear pending signals, and on NetBSD at least
    //    it does not.
    // 2) Replace the old signal handler now that we've completed the test. If
    //    the test fails this process panics, so the fact we might not get here
    //    is okay.
    drop(timer);
    thread::sleep(TIMER_PERIOD);
    unsafe {
        sigaction(SIG, &old_handler).expect("unable to reset signal handler");
    }
}

[ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge