use std::mem;
use crate::depot::queue::resident;
mod lane;
mod registry;
pub use lane::Lane;
pub use registry::Registry;
#[repr(transparent)]
pub struct Registration<'target, W, G, L> {
lease: resident::Lease<'target, Registry<W, G, L>>,
}
impl<W, G, L> Default for Registration<'_, W, G, L> {
fn default() -> Self {
Self::new()
}
}
impl<W, G, L> Registration<'_, W, G, L> {
pub const fn new() -> Self {
Self {
lease: resident::Lease::new(),
}
}
pub fn cancel(&mut self) -> Cancel<G> {
let Some((registry, key)) = self.lease.active() else {
return Cancel::Empty;
};
let key = *key;
self.lease.detach();
match registry.lanes.remove(key) {
resident::Removal::Linked => Cancel::Wake,
resident::Removal::Parked(entry) => Cancel::Grant(entry.take_grant()),
resident::Removal::Empty => Cancel::Empty,
}
}
pub fn take_grant(&mut self) -> Grant<G> {
let Some((registry, key)) = self.lease.active() else {
return Grant::Empty;
};
let Some(entry) = registry.lanes.claim(*key) else {
return Grant::Pending;
};
self.lease.detach();
Grant::Ready(entry.take_grant())
}
}
const _: () = {
assert!(
mem::size_of::<Registration<'static, usize, usize, resident::Fixed<2>>>()
== 2 * mem::size_of::<usize>()
);
assert!(
mem::align_of::<Registration<'static, usize, usize, resident::Fixed<2>>>()
== mem::align_of::<usize>()
);
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[must_use = "a rejected registration must be handled"]
pub enum Reject {
Active { index: usize },
Draining { index: usize },
Full { index: usize },
GrantPending { index: usize },
}
#[derive(Eq, PartialEq)]
#[must_use = "a rejected affine grant remains caller-owned"]
pub enum Offer<W, G> {
Value(W),
Draining(G),
Empty(G),
}
#[derive(Eq, PartialEq)]
pub enum Grant<G> {
Empty,
Pending,
Ready(G),
}
#[must_use = "a delivered affine grant remains caller-owned"]
#[derive(Eq, PartialEq)]
pub enum Cancel<G> {
Empty,
Wake,
Grant(G),
}