pub fn trigger()
Expand description

Trigger an interrupt, signalling to those checking for is_triggered() to stop what they are doing.

Examples found in repository?
src/interrupt.rs (line 96)
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    pub fn init_handler(interrupt: impl Fn() + Send + Sync + Clone + 'static) -> io::Result<Deregister> {
        if IS_INITIALIZED
            .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| Some(true))
            .expect("always returns value")
        {
            return Err(io::Error::new(io::ErrorKind::Other, "Already initialized"));
        }
        let mut hooks = Vec::with_capacity(signal_hook::consts::TERM_SIGNALS.len());
        for sig in signal_hook::consts::TERM_SIGNALS {
            // # SAFETY
            // * we only set atomics or call functions that do
            // * there is no use of the heap
            let interrupt = interrupt.clone();
            #[allow(unsafe_code)]
            unsafe {
                let hook_id = signal_hook::low_level::register(*sig, move || {
                    static INTERRUPT_COUNT: AtomicUsize = AtomicUsize::new(0);
                    if !super::is_triggered() {
                        INTERRUPT_COUNT.store(0, Ordering::SeqCst);
                    }
                    let msg_idx = INTERRUPT_COUNT.fetch_add(1, Ordering::SeqCst);
                    if msg_idx == 1 {
                        git_tempfile::handler::cleanup_tempfiles();
                        signal_hook::low_level::emulate_default_handler(*sig).ok();
                    }
                    interrupt();
                    super::trigger();
                })?;
                hooks.push((*sig, hook_id));
            }
        }

        // This means that they won't setup a handler allowing us to call them right before we actually abort.
        git_tempfile::setup(git_tempfile::SignalHandlerMode::None);

        Ok(Deregister(hooks))
    }