70 lines · 3.0 KB · Rust
RawDownload
#[cfg(feature = "interrupt")]mod needs_feature {    use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};     use signal_hook::consts::SIGTERM;     #[test]    fn multi_registration() -> gix_testtools::Result {        static V1: AtomicUsize = AtomicUsize::new(0);        static V2: AtomicBool = AtomicBool::new(false);         // SAFETY: The closure doesn't use mutexes or memory allocation, so it should be safe to call from a signal handler.        let reg1 = unsafe {            gix::interrupt::init_handler(3, || {                V1.fetch_add(1, Ordering::SeqCst);            })        }        .expect("succeeds");        assert!(!gix::interrupt::is_triggered());        assert_eq!(V1.load(Ordering::Relaxed), 0);        // SAFETY: The closure doesn't use mutexes or memory allocation, so it should be safe to call from a signal handler.        let reg2 = unsafe { gix::interrupt::init_handler(2, || V2.store(true, Ordering::SeqCst)) }            .expect("multi-initialization is OK");        assert!(!V2.load(Ordering::Relaxed));         signal_hook::low_level::raise(SIGTERM).expect("signal can be raised");        assert!(gix::interrupt::is_triggered(), "this happens automatically");        assert_eq!(V1.load(Ordering::Relaxed), 1, "the first trigger is invoked");        assert!(!V2.load(Ordering::Relaxed), "the second trigger was ignored");         reg1.deregister()?;        signal_hook::low_level::raise(SIGTERM).expect("signal can be raised");        assert_eq!(V1.load(Ordering::Relaxed), 2, "the first trigger is still invoked");         assert!(gix::interrupt::is_triggered(), "this happens automatically");        // now the registration is actually removed.        reg2.with_reset(true).deregister()?;        assert!(            !gix::interrupt::is_triggered(),            "the deregistration succeeded and this is an optional side-effect"        );         // SAFETY: The closure doesn't use mutexes or memory allocation, so it should be safe to call from a signal handler.        let reg1 = unsafe {            gix::interrupt::init_handler(3, || {                V1.fetch_add(1, Ordering::SeqCst);            })        }        .expect("succeeds");        assert_eq!(V1.load(Ordering::Relaxed), 2, "nothing changed yet");        // SAFETY: The closure doesn't use mutexes or memory allocation, so it should be safe to call from a signal handler.        let reg2 = unsafe { gix::interrupt::init_handler(2, || V2.store(true, Ordering::SeqCst)) }            .expect("multi-initialization is OK");        assert!(!V2.load(Ordering::Relaxed));         signal_hook::low_level::raise(SIGTERM).expect("signal can be raised");        assert_eq!(V1.load(Ordering::Relaxed), 3, "the first trigger is invoked");        assert!(!V2.load(Ordering::Relaxed), "the second trigger was ignored");         reg2.auto_deregister();        reg1.with_reset(true).auto_deregister();         assert!(            !gix::interrupt::is_triggered(),            "the deregistration succeeded and this is an optional side-effect"        );         Ok(())    }}