1//! Tests for the [unregister_signal] function.
2//!
3//! As a separate integration level test, so it doesn't clash with other tests on the signals.
4
5// The unregister_signal itself is deprecated. But we still want to test it, so it's not deprecated
6// and broken at the same time.
7#![allow(deprecated)]
8
9extern crate libc;
10extern crate signal_hook_registry;
11
12use std::sync::atomic::{AtomicUsize, Ordering};
13use std::sync::Arc;
14
15use libc::{SIGINT, SIGTERM}; // We'll use these here because SIGUSR1 is not available on Windows.
16use signal_hook_registry::{register, unregister_signal};
17
18#[test]
19fn register_unregister() {
20 let called = Arc::new(AtomicUsize::new(0));
21
22 let hook = {
23 let called = Arc::clone(&called);
24 move || {
25 called.fetch_add(1, Ordering::Relaxed);
26 }
27 };
28
29 unsafe {
30 register(SIGTERM, hook.clone()).unwrap();
31 register(SIGTERM, hook.clone()).unwrap();
32 register(SIGINT, hook.clone()).unwrap();
33
34 libc::raise(SIGTERM);
35 }
36
37 // The closure is run twice.
38 assert_eq!(2, called.load(Ordering::Relaxed));
39
40 assert!(unregister_signal(SIGTERM));
41
42 unsafe { libc::raise(SIGTERM) };
43 // Second one unregisters nothing.
44 assert!(!unregister_signal(SIGTERM));
45
46 // After unregistering (both), it is no longer run at all.
47 assert_eq!(2, called.load(Ordering::Relaxed));
48
49 // The SIGINT one is not disturbed.
50 unsafe { libc::raise(SIGINT) };
51 assert_eq!(3, called.load(Ordering::Relaxed));
52
53 // But it's possible to register it again just fine.
54 unsafe {
55 register(SIGTERM, hook).unwrap();
56 libc::raise(SIGTERM);
57 }
58 assert_eq!(4, called.load(Ordering::Relaxed));
59}
60