Skip to main content

dope_core/driver/ops/access/
receive.rs

1use std::io;
2
3use o3::buffer::resident;
4
5use crate::driver::{self, settings, storage::ownership};
6
7pub(super) struct State {
8    owners: ownership::Owners,
9    layout: settings::Receive,
10    pub(super) returned: ownership::Returned,
11}
12
13impl State {
14    pub(super) fn try_new(layout: settings::Receive) -> io::Result<Self> {
15        Ok(Self {
16            owners: ownership::Owners::try_new(layout)?,
17            layout,
18            returned: ownership::Returned::try_new(layout)?,
19        })
20    }
21}
22
23#[derive(Clone, Copy)]
24#[repr(transparent)]
25pub struct Receive<'d>(driver::Reference<'d>);
26
27impl<'d> Receive<'d> {
28    pub(in crate::driver) const fn new(driver: driver::Reference<'d>) -> Self {
29        Self(driver)
30    }
31
32    pub(crate) fn retain_buffer(self, buffer: driver::Buffer) -> driver::RecvOwner<'d> {
33        self.0.shared.receive.owners.acquire(buffer)
34    }
35
36    pub(crate) fn retain_recv_owner(self, owner: &driver::RecvOwner<'d>) -> driver::RecvOwner<'d> {
37        self.0.shared.receive.owners.retain(owner)
38    }
39
40    pub(crate) fn retain_accounted_buffer(
41        self,
42        buffer: driver::Buffer,
43        budget: &resident::Budget<'d>,
44    ) -> Result<driver::AccountedRecvOwner<'d>, driver::Buffer> {
45        self.0
46            .shared
47            .receive
48            .owners
49            .acquire_accounted(buffer, budget, self.layout().buffer_len())
50    }
51
52    pub(crate) fn retain_accounted_recv_owner(
53        self,
54        owner: &driver::RecvOwner<'d>,
55        budget: &resident::Budget<'d>,
56    ) -> Option<driver::AccountedRecvOwner<'d>> {
57        self.0
58            .shared
59            .receive
60            .owners
61            .retain_accounted(owner, budget, self.layout().buffer_len())
62    }
63
64    pub(crate) fn retain_existing_accounted_recv_owner(
65        self,
66        owner: &driver::AccountedRecvOwner<'d>,
67    ) -> driver::AccountedRecvOwner<'d> {
68        self.0
69            .shared
70            .receive
71            .owners
72            .retain_existing_accounted(owner)
73    }
74
75    pub(crate) fn release_recv_owner(self, owner: &driver::RecvOwner<'d>) {
76        if let Some(buffer) = self.0.shared.receive.owners.release(owner) {
77            self.0.shared.receive.returned.push(buffer);
78        }
79    }
80
81    pub(crate) fn release_accounted_recv_owner(self, owner: &driver::AccountedRecvOwner<'d>) {
82        if let Some(buffer) = self.0.shared.receive.owners.release_accounted(owner) {
83            self.0.shared.receive.returned.push(buffer);
84        }
85    }
86
87    pub(crate) fn layout(self) -> settings::Receive {
88        self.0.shared.receive.layout
89    }
90}
91
92const _: () = assert!(
93    std::mem::size_of::<Receive<'static>>() == std::mem::size_of::<driver::Reference<'static>>()
94);