1use std::{cell::RefCell, collections::HashSet, rc::Rc};
2
3use crate::driver::op::OpCanceller;
4
5#[derive(Clone)]
8pub struct CancelHandle {
9 shared: Rc<RefCell<Shared>>,
10}
11
12#[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 #[inline]
33 pub fn new() -> Self {
34 Default::default()
35 }
36
37 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 #[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}