use std::{pin, ptr};
use dope_core::{
driver::route,
io::{socket::msg, transfer},
};
use o3::collections::fixed::pinned::recycle;
use crate::{link::egress::queue::flight, wire::send};
unsafe impl<'d, const IOV: usize> recycle::raw::PoolOwner<'d, flight::Flight<IOV>>
for flight::Source<'d, IOV>
{
fn pool(self) -> ptr::NonNull<recycle::Pool<flight::Flight<IOV>>> {
self.pool
}
}
pub(in crate::link::egress::queue) trait Access<'a, const IOV: usize> {
fn reset(self);
fn push(self, iovec: msg::Iovec) -> bool;
fn mark(self, target: route::Token);
fn vectored(self) -> send::Vectored<'a>;
}
impl<'a, const IOV: usize> Access<'a, IOV> for pin::Pin<&'a mut flight::Flight<IOV>> {
fn reset(self) {
let flight = unsafe { self.get_unchecked_mut() };
flight.len = 0;
flight.bytes = transfer::Len::ZERO;
flight.target = None;
}
fn push(self, iovec: msg::Iovec) -> bool {
let flight = unsafe { self.get_unchecked_mut() };
let Some(bytes) = flight.bytes.checked_add(iovec.len()) else {
return false;
};
let Some(slot) = flight.iovecs.get_mut(flight.len) else {
return false;
};
flight.bytes = bytes;
*slot = iovec;
flight.len += 1;
true
}
fn mark(self, target: route::Token) {
let flight = unsafe { self.get_unchecked_mut() };
debug_assert!(flight.target.is_none());
flight.target = Some(target);
}
fn vectored(self) -> send::Vectored<'a> {
let flight = unsafe { self.get_unchecked_mut() };
let iovecs = &flight.iovecs[..flight.len];
let message =
unsafe { msg::raw::Vectored::retain((&mut flight.header, iovecs, flight.bytes)) };
send::Vectored::from_message(message)
}
}