use core::ptr::NonNull;
#[inline]
pub(crate) fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
struct AbortOnDrop;
impl Drop for AbortOnDrop {
fn drop(&mut self) {
panic!("aborting due to panic while changing lock ownership");
}
}
let guard = AbortOnDrop;
let result = f();
core::mem::forget(guard);
result
}
pub(crate) struct SharedGuardData<T: ?Sized>(NonNull<T>);
impl<T: ?Sized> SharedGuardData<T> {
#[inline]
pub(crate) fn new(data: &T) -> Self {
Self(NonNull::from(data))
}
#[inline]
pub(crate) unsafe fn as_ref(&self) -> &T {
unsafe { self.0.as_ref() }
}
}
unsafe impl<T: Sync + ?Sized> Send for SharedGuardData<T> {}
unsafe impl<T: Sync + ?Sized> Sync for SharedGuardData<T> {}
pub(crate) struct ExclusiveGuardData<T: ?Sized>(*mut T);
impl<T: ?Sized> ExclusiveGuardData<T> {
#[inline]
pub(crate) fn new(data: &mut T) -> Self {
Self(data)
}
#[inline]
pub(crate) unsafe fn as_ref(&self) -> &T {
unsafe { self.0.as_ref_unchecked() }
}
#[inline]
pub(crate) unsafe fn as_mut(&mut self) -> &mut T {
unsafe { self.0.as_mut_unchecked() }
}
}
unsafe impl<T: Send + ?Sized> Send for ExclusiveGuardData<T> {}
unsafe impl<T: Sync + ?Sized> Sync for ExclusiveGuardData<T> {}