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}