Skip to main content

ort_openrouter_cli/common/
cancel_token.rs

1//! ort: Open Router CLI
2//! https://github.com/grahamking/ort
3//!
4//! MIT License
5//! Copyright (c) 2025 Graham King
6
7use core::sync::atomic::{AtomicBool, Ordering};
8use core::{mem, ptr};
9
10use crate::libc;
11
12static CANCELLED: AtomicBool = AtomicBool::new(false);
13static IS_INIT_DONE: AtomicBool = AtomicBool::new(false);
14
15// A way to stop a running thread
16// Loosely inspired by tokio's CancellationToken
17#[derive(Clone, Copy)]
18pub struct CancelToken(&'static AtomicBool);
19
20impl CancelToken {
21    pub fn init() -> Self {
22        // If IS_INIT_DONE == false, atomically make it true
23        if IS_INIT_DONE
24            .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
25            .is_ok()
26        {
27            // We changed the flag, so we are the first
28            unsafe { install_sigint_handler() };
29        }
30        CancelToken(&CANCELLED)
31    }
32
33    pub fn cancel(&self) {
34        self.0.store(true, Ordering::SeqCst);
35    }
36
37    pub fn is_cancelled(&self) -> bool {
38        self.0.load(Ordering::Relaxed)
39    }
40}
41
42extern "C" fn handle_sigint(_: i32) {
43    CANCELLED.store(true, Ordering::SeqCst);
44}
45
46unsafe fn install_sigint_handler() {
47    const SIGINT: i32 = 2;
48    unsafe {
49        let mut sa: libc::sigaction = mem::zeroed();
50        sa.sa_flags = 0;
51        sa.sa_sigaction = handle_sigint as *const () as usize; // treated as sa_handler when SA_SIGINFO not set
52        libc::sigemptyset(&mut sa.sa_mask);
53        libc::sigaction(SIGINT, &sa, ptr::null_mut());
54    }
55}