Skip to main content

dope_core/driver/ops/access/
outbound.rs

1use std::process;
2
3use crate::{backend::fixed, driver, io::fd::handles};
4
5#[derive(Clone, Copy)]
6#[repr(transparent)]
7pub struct Outbound<'d>(driver::Reference<'d>);
8
9impl<'d> Outbound<'d> {
10    pub(in crate::driver) const fn new(driver: driver::Reference<'d>) -> Self {
11        Self(driver)
12    }
13
14    pub(in crate::driver) fn is_unopened(
15        self,
16        key: driver::OutboundKey,
17        slot: handles::FixedSlot,
18    ) -> bool {
19        self.0
20            .shared
21            .files
22            .leases
23            .borrow_mut()
24            .issues()
25            .is_unopened(key, slot)
26    }
27
28    pub(crate) fn begin_outbound_create(
29        self,
30        key: driver::OutboundKey,
31        slot: handles::FixedSlot,
32    ) -> bool {
33        self.0
34            .shared
35            .files
36            .leases
37            .borrow_mut()
38            .issues()
39            .begin_create(key, slot)
40    }
41
42    pub(crate) fn begin_outbound_create_for(self, slot: handles::FixedSlot) -> bool {
43        let driver::FixedOwner::Outbound(key) = self.0.files().fixed_owner(slot) else {
44            return false;
45        };
46        self.begin_outbound_create(key, slot)
47    }
48
49    pub(crate) fn begin_outbound_close(
50        self,
51        key: driver::OutboundKey,
52        slot: handles::FixedSlot,
53    ) -> driver::CloseDisposition<'d> {
54        let result = self
55            .0
56            .shared
57            .files
58            .leases
59            .borrow_mut()
60            .issues()
61            .begin_close(key, slot);
62        match result {
63            Ok((true, None)) => driver::CloseDisposition::Submit(driver::Close::tracked(slot)),
64            Ok((false, slots)) => {
65                driver::CloseDisposition::NoSubmit(slots.map(driver::RetiredSlots::new))
66            }
67            Ok((true, Some(_))) | Err(()) => process::abort(),
68        }
69    }
70
71    pub(crate) fn close_disposition(
72        self,
73        slot: handles::FixedSlot,
74        outbound: Option<driver::OutboundKey>,
75    ) -> driver::CloseDisposition<'d> {
76        match outbound {
77            Some(outbound) => self.begin_outbound_close(outbound, slot),
78            None => driver::CloseDisposition::Submit(driver::Close::untracked(slot)),
79        }
80    }
81
82    pub(crate) fn complete_outbound_close(
83        self,
84        slot: handles::FixedSlot,
85    ) -> Option<driver::RetiredSlots<'d>> {
86        let result = self
87            .0
88            .shared
89            .files
90            .leases
91            .borrow_mut()
92            .issues()
93            .complete_close(slot);
94        match result {
95            Ok(slots) => slots.map(driver::RetiredSlots::new),
96            Err(()) => process::abort(),
97        }
98    }
99
100    pub(crate) fn release_outbound_slot(
101        self,
102        key: driver::OutboundKey,
103        slot: handles::FixedSlot,
104    ) -> Option<driver::RetiredSlots<'d>> {
105        let result = self
106            .0
107            .shared
108            .files
109            .leases
110            .borrow_mut()
111            .issues()
112            .release_unopened(key, slot);
113        match result {
114            Ok(slots) => slots.map(driver::RetiredSlots::new),
115            Err(()) => process::abort(),
116        }
117    }
118
119    pub(crate) fn release_outbound_slot_for(
120        self,
121        slot: handles::FixedSlot,
122    ) -> Option<driver::RetiredSlots<'d>> {
123        let driver::FixedOwner::Outbound(key) = self.0.files().fixed_owner(slot) else {
124            process::abort();
125        };
126        self.release_outbound_slot(key, slot)
127    }
128
129    pub(crate) fn complete_outbound_create_success(
130        self,
131        slot: handles::FixedSlot,
132    ) -> driver::CreateSuccess<'d> {
133        use crate::driver::ops::access::files::leases::CreateTransition;
134
135        let result = self
136            .0
137            .shared
138            .files
139            .leases
140            .borrow_mut()
141            .issues()
142            .complete_create_success(slot);
143        match result {
144            Ok(CreateTransition::Deliver(key)) => driver::CreateSuccess::Deliver(key),
145            Ok(CreateTransition::Close) => {
146                driver::CreateSuccess::Close(driver::Close::tracked(slot))
147            }
148            Err(()) => process::abort(),
149        }
150    }
151
152    pub(crate) fn complete_outbound_create_failure(
153        self,
154        slot: handles::FixedSlot,
155    ) -> Option<driver::RetiredSlots<'d>> {
156        let result = self
157            .0
158            .shared
159            .files
160            .leases
161            .borrow_mut()
162            .issues()
163            .complete_create_failure(slot);
164        match result {
165            Ok(slots) => slots.map(driver::RetiredSlots::new),
166            Err(()) => process::abort(),
167        }
168    }
169
170    pub(crate) fn activate_outbound(
171        self,
172        key: driver::OutboundKey,
173        slot: handles::FixedSlot,
174    ) -> bool {
175        self.0
176            .shared
177            .files
178            .leases
179            .borrow_mut()
180            .issues()
181            .activate(key, slot)
182    }
183
184    pub(crate) fn release_outbound_owner(
185        self,
186        key: driver::OutboundKey,
187    ) -> Option<driver::RetiredSlots<'d>> {
188        self.0
189            .shared
190            .files
191            .leases
192            .borrow_mut()
193            .release_owner(key)
194            .map(driver::RetiredSlots::new)
195    }
196
197    pub(crate) fn take_retired_slots(
198        self,
199        retired: driver::RetiredSlots<'d>,
200    ) -> fixed::Reservation<'d> {
201        self.0
202            .shared
203            .files
204            .leases
205            .borrow_mut()
206            .take_retired(retired)
207    }
208}
209
210const _: () = assert!(
211    std::mem::size_of::<Outbound<'static>>() == std::mem::size_of::<driver::Reference<'static>>()
212);