mod cell;
pub(in crate::link::oneshot) use cell::Cell;
use dope_core::{
driver::{self, result, route::Identity},
io::{
event::net::{connect, send, socket::Completion},
socket,
},
};
use o3::depot::{self, arena::slab::external::errors};
use crate::link::{
egress::data,
oneshot::{
Pool, Progress,
entry::{Access, Entry},
},
};
pub struct Io<'a, 'turn, 'd, ID: Identity, A: 'd, P: socket::Prepared, B: 'd>
where
B: data::raw::Payload<'d> + data::raw::StableOwner<'d>,
{
pool: &'a mut Pool<'d, ID, A, P, B>,
driver: &'a mut driver::Context<'turn, 'd>,
}
impl<'a, 'turn, 'd, ID: Identity, A: 'd, P: socket::Prepared, B: 'd> Io<'a, 'turn, 'd, ID, A, P, B>
where
B: data::raw::Payload<'d> + data::raw::StableOwner<'d>,
{
pub unsafe fn new(
pool: &'a mut Pool<'d, ID, A, P, B>,
driver: &'a mut driver::Context<'turn, 'd>,
) -> Self {
Self { pool, driver }
}
pub fn socket(&mut self, done: Completion<'d>) -> Progress<A> {
let local = match self.pool.routes.parse(done.token()) {
Ok(local) => local,
Err(_) => {
done.reclaim();
return Progress::Idle;
}
};
let access =
Access::new(unsafe { depot::raw::Proof::new((&mut *self.pool, local.index())) });
match Entry::try_new(access, local.parts().epoch()) {
Ok(entry) => entry.socket(done, self.driver),
Err(errors::Lookup::Physical { .. } | errors::Lookup::Generation { .. }) => {
done.reclaim();
Progress::Idle
}
}
}
pub fn connect(
&mut self,
done: connect::Completion<'d>,
) -> Result<Progress<A>, connect::Completion<'d>> {
let local = match self.pool.routes.parse(done.token()) {
Ok(local) => local,
Err(_) => {
return Err(done);
}
};
let access =
Access::new(unsafe { depot::raw::Proof::new((&mut *self.pool, local.index())) });
match Entry::try_new(access, local.parts().epoch()) {
Ok(entry) => entry.connect(done, self.driver),
Err(errors::Lookup::Physical { .. } | errors::Lookup::Generation { .. }) => Err(done),
}
}
pub fn send(
&mut self,
done: send::Completion<'d>,
) -> Result<Progress<A>, send::Completion<'d>> {
let local = match self.pool.routes.parse(done.token()) {
Ok(local) => local,
Err(_) => {
return Err(done);
}
};
let access =
Access::new(unsafe { depot::raw::Proof::new((&mut *self.pool, local.index())) });
match Entry::try_new(access, local.parts().epoch()) {
Ok(entry) => entry.send(done, self.driver),
Err(errors::Lookup::Physical { .. } | errors::Lookup::Generation { .. }) => Err(done),
}
}
pub fn retry_one(&mut self) -> Result<Progress<A>, result::SubmitError> {
let Some(local) = self.pool.retries.pop_front() else {
return Ok(Progress::Idle);
};
let access =
Access::new(unsafe { depot::raw::Proof::new((&mut *self.pool, local.index())) });
match Entry::try_new(access, local.parts().epoch()) {
Ok(entry) => entry.retry(self.driver),
Err(errors::Lookup::Physical { .. } | errors::Lookup::Generation { .. }) => {
Ok(Progress::Idle)
}
}
}
}