use core::cell::Cell;
use core::marker::PhantomData;
use crate::runtime::{config::Clock, consts::LabelUniverse};
use crate::{
control::cap::mint::EpochTbl, control::types::Lane, rendezvous::core::Rendezvous,
transport::Transport,
};
pub(crate) struct LaneGuard<'lease, T: Transport, U: LabelUniverse, C: Clock> {
rendezvous: *const (),
lane: Lane,
active_leases: &'lease Cell<u32>,
_marker: PhantomData<fn() -> (T, U, C)>,
}
impl<'lease, T, U, C> LaneGuard<'lease, T, U, C>
where
T: Transport,
U: LabelUniverse,
C: Clock,
{
pub(crate) fn new_detached(
rendezvous: *const (),
lane: Lane,
active_leases: &'lease Cell<u32>,
) -> Self {
Self {
rendezvous,
lane,
active_leases,
_marker: PhantomData,
}
}
#[inline]
pub(crate) fn detach_rendezvous(&mut self) {
self.rendezvous = core::ptr::null();
}
}
impl<'lease, T, U, C> Drop for LaneGuard<'lease, T, U, C>
where
T: Transport,
U: LabelUniverse,
C: Clock,
{
fn drop(&mut self) {
let lane = self.lane;
if !self.rendezvous.is_null() {
unsafe {
let rv = &*self
.rendezvous
.cast::<Rendezvous<'static, 'static, T, U, C, EpochTbl>>();
if let Some(sid) = rv.release_lane(lane) {
rv.emit_lane_release(sid, lane);
}
}
}
let current = self.active_leases.get();
debug_assert!(current > 0, "lane_release underflow");
self.active_leases.set(current.saturating_sub(1));
}
}