monoio/io/util/
cancel.rs

1use std::{cell::RefCell, collections::HashSet, rc::Rc};
2
3use crate::driver::op::OpCanceller;
4
5/// CancelHandle is used to pass to io actions with CancelableAsyncReadRent.
6/// Create a CancelHandle with Canceller::handle.
7#[derive(Clone)]
8pub struct CancelHandle {
9    shared: Rc<RefCell<Shared>>,
10}
11
12/// Canceller is a user-hold struct to cancel io operations.
13/// A canceller can associate with multiple io operations.
14#[derive(Default)]
15pub struct Canceller {
16    shared: Rc<RefCell<Shared>>,
17}
18
19pub(crate) struct AssociateGuard {
20    op_canceller: OpCanceller,
21    shared: Rc<RefCell<Shared>>,
22}
23
24#[derive(Default)]
25struct Shared {
26    canceled: bool,
27    slot_ref: HashSet<OpCanceller>,
28}
29
30impl Canceller {
31    /// Create a new Canceller.
32    #[inline]
33    pub fn new() -> Self {
34        Default::default()
35    }
36
37    /// Cancel all related operations.
38    pub fn cancel(self) -> Self {
39        let mut slot = HashSet::new();
40        {
41            let mut shared = self.shared.borrow_mut();
42            shared.canceled = true;
43            std::mem::swap(&mut slot, &mut shared.slot_ref);
44        }
45
46        for op_canceller in slot.iter() {
47            unsafe { op_canceller.cancel() };
48        }
49        slot.clear();
50        Canceller {
51            shared: Rc::new(RefCell::new(Shared {
52                canceled: false,
53                slot_ref: slot,
54            })),
55        }
56    }
57
58    /// Create a CancelHandle which can be used to pass to io operation.
59    #[inline]
60    pub fn handle(&self) -> CancelHandle {
61        CancelHandle {
62            shared: self.shared.clone(),
63        }
64    }
65}
66
67impl CancelHandle {
68    pub(crate) fn canceled(&self) -> bool {
69        self.shared.borrow().canceled
70    }
71
72    pub(crate) fn associate_op(self, op_canceller: OpCanceller) -> AssociateGuard {
73        {
74            let mut shared = self.shared.borrow_mut();
75            shared.slot_ref.insert(op_canceller.clone());
76        }
77        AssociateGuard {
78            op_canceller,
79            shared: self.shared,
80        }
81    }
82}
83
84impl Drop for AssociateGuard {
85    fn drop(&mut self) {
86        let mut shared = self.shared.borrow_mut();
87        shared.slot_ref.remove(&self.op_canceller);
88    }
89}
90
91pub(crate) fn operation_canceled() -> std::io::Error {
92    std::io::Error::from_raw_os_error(125)
93}