use std::marker;
use dope_sys::Errno;
use o3::base::{cell::region, marker::ThreadBound};
use crate::{
driver::{self, life::Final, receive::credit, schedule::clock},
io::event::net::recv,
};
#[must_use]
pub struct Finish<'a, 'd> {
last: Final<'a, 'd>,
forced: bool,
disarm: Option<Errno>,
}
impl<'a, 'd> Finish<'a, 'd> {
pub(super) fn new(last: Final<'a, 'd>, forced: bool) -> Self {
Self {
last,
forced,
disarm: None,
}
}
pub(super) fn resume(self) {
self.last.resume();
}
pub fn is_forced(&self) -> bool {
self.forced
}
pub fn fail_disarm(&mut self, cause: Errno) {
if self.disarm.is_none() {
self.disarm = Some(cause);
}
}
pub fn disarm_error(&self) -> Option<Errno> {
self.disarm
}
pub fn clock<'f>(&'f self) -> clock::Clock<'f, 'd> {
self.last.context().driver_ref().clock()
}
pub fn reclaim(&mut self, done: recv::Completion<'d>) {
self.last.context_mut().reclaim(done);
}
pub fn region_token<'f>(&'f mut self) -> &'f mut region::Token<region::Identity<'d>> {
self.last.context_mut().region_token()
}
pub fn state_token<'f>(&'f mut self) -> &'f mut region::Token<region::Identity<'d, 1>> {
self.last.context_mut().state_token()
}
pub(in crate::driver) fn brand(&self) -> driver::Invariant<'d> {
self.last.context().driver_ref().brand
}
pub fn credit<'f>(&'f mut self) -> Credit<'f, 'd> {
Credit::new(self.brand())
}
}
const _: () = {
assert!(
std::mem::size_of::<Finish<'static, 'static>>()
== std::mem::size_of::<(Final<'static, 'static>, bool)>()
);
};
#[repr(transparent)]
pub struct Credit<'a, 'd> {
borrow: marker::PhantomData<(&'a mut (), driver::Invariant<'d>, ThreadBound)>,
}
impl<'a, 'd> Credit<'a, 'd> {
const fn new(_brand: driver::Invariant<'d>) -> Self {
Self {
borrow: marker::PhantomData,
}
}
pub fn detach(self, storage: &credit::Storage<'d>) {
for slot in storage.entries.iter() {
slot.detach();
}
}
}
const _: () = {
assert!(std::mem::size_of::<Credit<'static, 'static>>() == 0);
};