Skip to main content

runmat_runtime/
interrupt.rs

1use runmat_thread_local::runmat_thread_local;
2use std::cell::RefCell;
3use std::sync::{
4    atomic::{AtomicBool, Ordering},
5    Arc,
6};
7
8runmat_thread_local! {
9    static INTERRUPT_HANDLE: RefCell<Option<Arc<AtomicBool>>> = const { RefCell::new(None) };
10}
11
12pub struct InterruptGuard {
13    previous: Option<Arc<AtomicBool>>,
14}
15
16impl InterruptGuard {
17    pub fn install(handle: Option<Arc<AtomicBool>>) -> Self {
18        let previous = INTERRUPT_HANDLE.with(|slot| slot.replace(handle));
19        Self { previous }
20    }
21}
22
23impl Drop for InterruptGuard {
24    fn drop(&mut self) {
25        INTERRUPT_HANDLE.with(|slot| {
26            slot.replace(self.previous.take());
27        });
28    }
29}
30
31pub fn replace_interrupt(handle: Option<Arc<AtomicBool>>) -> InterruptGuard {
32    InterruptGuard::install(handle)
33}
34
35pub fn is_cancelled() -> bool {
36    INTERRUPT_HANDLE.with(|slot| {
37        slot.borrow()
38            .as_ref()
39            .map(|flag| flag.load(Ordering::Relaxed))
40            .unwrap_or(false)
41    })
42}