blob: 67c617c2f1f515bc3b5a0e38d597140753e992fc [file] [log] [blame]
//! Tests for the [unregister_signal] function.
//!
//! As a separate integration level test, so it doesn't clash with other tests on the signals.
extern crate libc;
extern crate signal_hook_registry;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use libc::{SIGINT, SIGTERM}; // We'll use these here because SIGUSR1 is not available on Windows.
use signal_hook_registry::{register, unregister_signal};
#[test]
fn register_unregister() {
let called = Arc::new(AtomicUsize::new(0));
let hook = {
let called = Arc::clone(&called);
move || {
called.fetch_add(1, Ordering::Relaxed);
}
};
unsafe {
register(SIGTERM, hook.clone()).unwrap();
register(SIGTERM, hook.clone()).unwrap();
register(SIGINT, hook.clone()).unwrap();
libc::raise(SIGTERM);
}
// The closure is run twice.
assert_eq!(2, called.load(Ordering::Relaxed));
assert!(unregister_signal(SIGTERM));
unsafe { libc::raise(SIGTERM) };
// Second one unregisters nothing.
assert!(!unregister_signal(SIGTERM));
// After unregistering (both), it is no longer run at all.
assert_eq!(2, called.load(Ordering::Relaxed));
// The SIGINT one is not disturbed.
unsafe { libc::raise(SIGINT) };
assert_eq!(3, called.load(Ordering::Relaxed));
// But it's possible to register it again just fine.
unsafe {
register(SIGTERM, hook).unwrap();
libc::raise(SIGTERM);
}
assert_eq!(4, called.load(Ordering::Relaxed));
}