use std::mem;
use dope_core::driver::{
result, route,
route::{
Identity, KeyTag,
table::{self, conn},
},
};
use o3::{
depot,
depot::{
arena::slab::external::errors,
queue::indexed::{exact, fifo},
},
};
pub use receiver::Receiver;
use crate::{
link::{duplex, event, pool},
wire,
wire::receive::{Chunk, mode::Disabled},
};
pub mod arrival;
pub mod delivery;
pub mod input;
mod receiver;
pub mod reserve;
pub mod storage;
pub enum Ready<'d> {
Completion(event::Completion<'d>),
Empty,
Paused,
Stale,
}
pub enum Readiness {
Ready,
Empty,
Paused,
Stale,
}
pub struct Missing<'d, ID: Identity> {
pub key: pool::Key<'d, ID>,
pub cause: errors::Lookup<route::Epoch, ID>,
}
#[derive(Debug)]
pub struct Failure<'d, ID: Identity> {
pub key: pool::Key<'d, ID>,
pub cause: result::SubmitError,
}
pub enum Resumption<'d, ID: Identity> {
Unavailable(Missing<'d, ID>),
Ready(delivery::Resumed<'d, ID>),
}
pub enum Deferral<'w, 'd, W: wire::Spec + 'w> {
Ready,
Unavailable(Chunk<'w, 'd, W, Disabled>),
Occupied(Chunk<'w, 'd, W, Disabled>),
Full(Chunk<'w, 'd, W, Disabled>),
}
pub(in crate::link::pool) struct State<'d, ID: Identity, P: storage::raw::Mode> {
pub(in crate::link::pool) rearm:
fifo::List<pool::Key<'d, ID>, pool::raw::Physical<'d, ID>, exact::Policy>,
pub(in crate::link::pool) storage: P::Storage<'d>,
}
pub(in crate::link::pool) struct Borrow<'a, 'd: 'a, ID: Identity, P: storage::raw::Mode> {
pub(in crate::link::pool) rearm: Rearm<'a, 'd, ID>,
pub(in crate::link::pool) storage: P::Bound<'a, 'd>,
}
impl<'d, ID: Identity, P: storage::raw::Mode> State<'d, ID, P> {
pub(in crate::link::pool) fn try_new(
cap: conn::Capacity,
storage: P::Storage<'d>,
) -> crate::Result<Self> {
Ok(Self {
rearm: fifo::List::try_count(table::Capacity::from(cap))
.map_err(crate::Resource::Allocation)?,
storage,
})
}
}
pub(in crate::link::pool) struct Rearm<'a, 'd, ID: Identity> {
entry: exact::Entry<'a, pool::Key<'d, ID>, pool::raw::Physical<'d, ID>>,
key: pool::Key<'d, ID>,
}
impl<'d, ID: Identity> Rearm<'_, 'd, ID> {
pub(in crate::link::pool) fn key(&self) -> pool::Key<'d, ID> {
self.key
}
pub(in crate::link::pool) fn queue(&mut self) {
self.entry.schedule(self.key);
}
pub(in crate::link::pool) fn remove(&mut self) {
self.entry.unlink(self.key);
}
pub(in crate::link::pool) fn submitted(
&mut self,
submit: Result<duplex::Rearm, result::SubmitError>,
) -> Result<(), Failure<'d, ID>> {
let submit = match submit {
Ok(submit) => submit,
Err(cause) => {
self.remove();
return Err(Failure {
key: self.key,
cause,
});
}
};
if submit.is_needed() {
self.queue();
}
Ok(())
}
}
unsafe impl<'a, 'd: 'a, ID: Identity, P: storage::raw::Mode> depot::raw::Project<pool::Key<'d, ID>>
for &'a mut State<'d, ID, P>
{
type Output = Borrow<'a, 'd, ID, P>;
unsafe fn project(self, key: pool::Key<'d, ID>) -> Self::Output {
use o3::depot::raw::Proof;
let index = pool::raw::Physical::bind(key);
let entry = unsafe { Proof::new((&mut self.rearm, index)) }.into();
let slot = unsafe { Proof::new((&mut self.storage, key.index().into_usize())) };
let storage = P::bind(slot);
Borrow {
rearm: Rearm { entry, key },
storage,
}
}
}
const _: () = {
assert!(mem::size_of::<Rearm<'static, 'static, KeyTag<0>>>() == 32);
assert!(mem::size_of::<Option<Rearm<'static, 'static, KeyTag<0>>>>() == 32);
};