use core::cell::Cell;
use core::marker::PhantomData;
use crate::{
rendezvous::core::{LaneRelease, Rendezvous},
session::types::{Lane, SessionId},
transport::Transport,
};
pub(crate) struct LaneGuard<'lease, T: Transport> {
rendezvous: *const (),
sid: SessionId,
lane: Lane,
active_leases: &'lease Cell<u32>,
_marker: PhantomData<fn() -> T>,
}
impl<'lease, T> LaneGuard<'lease, T>
where
T: Transport,
{
pub(crate) fn new_detached(
rendezvous: *const (),
sid: SessionId,
lane: Lane,
active_leases: &'lease Cell<u32>,
) -> Self {
Self {
rendezvous,
sid,
lane,
active_leases,
_marker: PhantomData,
}
}
}
impl<'lease, T> Drop for LaneGuard<'lease, T>
where
T: Transport,
{
fn drop(&mut self) {
let sid = self.sid;
let lane = self.lane;
if !self.rendezvous.is_null() {
unsafe {
let rv = &*self.rendezvous.cast::<Rendezvous<'static, 'static, T>>();
match rv.release_lane(sid, lane) {
LaneRelease::Released => rv.emit_lane_release(sid, lane),
LaneRelease::StillHeld => {}
}
}
}
let current = self.active_leases.get();
if current == 0 {
crate::invariant();
}
self.active_leases.set(current - 1);
}
}