Skip to main content

unlab_gpu/
intr.rs

1//
2// Copyright (c) 2025-2026 Ɓukasz Szpakowski
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7//
8//! An interruption module.
9use std::sync::atomic::AtomicBool;
10use std::sync::atomic::Ordering;
11use crate::ctrlc;
12use crate::error::*;
13
14/// A trait of interruption checker.
15///
16/// The interruption checker is used by a `checkintr` built-in function to check whether an
17/// interruption is occurred. If the interruption is occurred, this built-in function returns an
18/// interruption error.
19pub trait IntrCheck
20{
21    /// Checks whether an interruption is occurred.
22    ///
23    /// This method returns an interruption error if the interruption is occurred.
24    fn check(&self) -> Result<()>;
25}
26
27/// A structure of empty interruption checker.
28///
29/// The empty interruption checker is dummy that ignores interruptions.
30#[derive(Copy, Clone, Debug)]
31pub struct EmptyIntrChecker;
32
33impl EmptyIntrChecker
34{
35    /// Create an empty interruption checker.
36    pub fn new() -> Self
37    { EmptyIntrChecker }
38}
39
40impl IntrCheck for EmptyIntrChecker
41{
42    fn check(&self) -> Result<()>
43    { Ok(()) }
44}
45
46static INTR_FLAG: AtomicBool = AtomicBool::new(false);
47
48/// A structure of `Ctrl-C` interruption checker.
49///
50/// The `Ctrl-C` interruption checker checks whether keys `Ctrl-C` are pressed. If the keys
51/// `Ctrl-C` is pressed, the `Ctrl-C` interruption checker interprets it as an interruption.
52#[derive(Copy, Clone, Debug)]
53pub struct CtrlCIntrChecker;
54
55impl CtrlCIntrChecker
56{
57    /// Creates an Ctrl-C` interruption checker.
58    pub fn new() -> Self
59    { CtrlCIntrChecker }
60    
61    /// Initializes the Ctrl-C` interruption checker.
62    pub fn initialize() -> Result<()>
63    {
64        match ctrlc::set_handler(move || INTR_FLAG.store(true, Ordering::SeqCst)) {
65            Ok(()) => Ok(()),
66            Err(err) => Err(Error::Ctrlc(err)),
67        }
68    }
69    
70    /// Resets the Ctrl-C` interruption checker.
71    pub fn reset()
72    { INTR_FLAG.store(false, Ordering::SeqCst); }
73}
74
75impl IntrCheck for CtrlCIntrChecker
76{
77    fn check(&self) -> Result<()>
78    {
79        if INTR_FLAG.swap(false, Ordering::SeqCst) {
80            Err(Error::Intr)
81        } else {
82            Ok(())
83        }
84    }
85}