pub trait Lifetime<'this, ImplicitBounds: bounds::Sealed = bounds::Bounds<&'this Self>> {
type ExclusiveGuard;
type SharedGuard;
}
pub unsafe trait Lock: for<'this> Lifetime<'this> {
fn lock_exclusive(&self) -> <Self as Lifetime<'_>>::ExclusiveGuard;
fn lock_shared(&self) -> <Self as Lifetime<'_>>::SharedGuard;
}
macro_rules! impl_for_wrapper {
($($t:ty),*) => { $(
impl<'this, L: Lock> Lifetime<'this> for $t {
type ExclusiveGuard = <L as Lifetime<'this>>::ExclusiveGuard;
type SharedGuard = <L as Lifetime<'this>>::SharedGuard;
}
unsafe impl<L: Lock> Lock for $t {
fn lock_exclusive(&self) -> <Self as Lifetime<'_>>::ExclusiveGuard {
(**self).lock_exclusive()
}
fn lock_shared(&self) -> <Self as Lifetime<'_>>::SharedGuard {
(**self).lock_shared()
}
}
)* };
}
impl_for_wrapper!(&L, &mut L);
#[cfg(feature = "alloc")]
impl_for_wrapper!(alloc::boxed::Box<L>, alloc::rc::Rc<L>, alloc::sync::Arc<L>);
pub mod local {
use crate::lock;
use crate::lock::Lock;
use core::cell::Cell;
use core::cell::UnsafeCell;
use core::ops::Deref;
use core::ops::DerefMut;
#[derive(Debug)]
pub struct Local<T> {
locked: Cell<bool>,
data: UnsafeCell<T>,
}
impl<T> Local<T> {
#[must_use]
pub const fn new(value: T) -> Self {
Self {
locked: Cell::new(false),
data: UnsafeCell::new(value),
}
}
#[must_use]
pub fn get_mut(&mut self) -> &mut T {
self.data.get_mut()
}
#[must_use]
pub fn into_inner(self) -> T {
self.data.into_inner()
}
#[must_use]
pub fn is_locked(&self) -> bool {
self.locked.get()
}
}
impl<T: Default> Default for Local<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> From<T> for Local<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<'this, T> lock::Lifetime<'this> for Local<T> {
type ExclusiveGuard = Guard<'this, T>;
type SharedGuard = Guard<'this, T>;
}
unsafe impl<T> Lock for Local<T> {
#[track_caller]
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
assert!(!self.is_locked(), "Attempted to recursively lock `Local`");
self.locked.set(true);
Guard { lock: self }
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.lock_exclusive()
}
}
#[derive(Debug)]
pub struct Guard<'lock, T> {
lock: &'lock Local<T>,
}
impl<T> Deref for Guard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.lock.data.get() }
}
}
impl<T> DerefMut for Guard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.lock.data.get() }
}
}
impl<T> Drop for Guard<'_, T> {
fn drop(&mut self) {
debug_assert!(self.lock.is_locked());
self.lock.locked.set(false);
}
}
}
#[doc(no_inline)]
pub use local::Local;
mod ref_cell {
use crate::lock;
use crate::lock::Lock;
use core::cell;
use core::cell::RefCell;
impl<'this, T> lock::Lifetime<'this> for RefCell<T> {
type ExclusiveGuard = cell::RefMut<'this, T>;
type SharedGuard = cell::Ref<'this, T>;
}
unsafe impl<T> Lock for RefCell<T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.borrow_mut()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.borrow()
}
}
}
#[cfg(feature = "std")]
mod std {
use crate::lock;
use crate::lock::Lock;
use std::sync::Mutex;
use std::sync::MutexGuard;
use std::sync::RwLock;
use std::sync::RwLockReadGuard;
use std::sync::RwLockWriteGuard;
#[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
impl<'this, T> lock::Lifetime<'this> for Mutex<T> {
type ExclusiveGuard = MutexGuard<'this, T>;
type SharedGuard = MutexGuard<'this, T>;
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
unsafe impl<T> Lock for Mutex<T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.lock().unwrap()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.lock_exclusive()
}
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
impl<'this, T> lock::Lifetime<'this> for RwLock<T> {
type ExclusiveGuard = RwLockWriteGuard<'this, T>;
type SharedGuard = RwLockReadGuard<'this, T>;
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
unsafe impl<T> Lock for RwLock<T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.write().unwrap()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.read().unwrap()
}
}
}
#[cfg(feature = "lock_api_04")]
mod lock_api_04 {
use crate::lock;
use crate::lock::Lock;
use lock_api_04::Mutex;
use lock_api_04::MutexGuard;
use lock_api_04::RawMutex;
use lock_api_04::RawRwLock;
use lock_api_04::RwLock;
use lock_api_04::RwLockReadGuard;
use lock_api_04::RwLockWriteGuard;
#[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
impl<'this, R: RawMutex, T> lock::Lifetime<'this> for Mutex<R, T> {
type ExclusiveGuard = MutexGuard<'this, R, T>;
type SharedGuard = MutexGuard<'this, R, T>;
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
unsafe impl<R: RawMutex, T> Lock for Mutex<R, T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.lock()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.lock_exclusive()
}
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
impl<'this, R: RawRwLock, T> lock::Lifetime<'this> for RwLock<R, T> {
type ExclusiveGuard = RwLockWriteGuard<'this, R, T>;
type SharedGuard = RwLockReadGuard<'this, R, T>;
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
unsafe impl<R: RawRwLock, T> Lock for RwLock<R, T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.write()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.read()
}
}
}
#[cfg(feature = "loom_05")]
mod loom_05 {
use crate::lock;
use crate::lock::Lock;
use loom_05_crate::sync::Mutex;
use loom_05_crate::sync::MutexGuard;
use loom_05_crate::sync::RwLock;
use loom_05_crate::sync::RwLockReadGuard;
use loom_05_crate::sync::RwLockWriteGuard;
#[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
impl<'this, T> lock::Lifetime<'this> for Mutex<T> {
type ExclusiveGuard = MutexGuard<'this, T>;
type SharedGuard = MutexGuard<'this, T>;
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
unsafe impl<T> Lock for Mutex<T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.lock().unwrap()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.lock_exclusive()
}
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
impl<'this, T> lock::Lifetime<'this> for RwLock<T> {
type ExclusiveGuard = RwLockWriteGuard<'this, T>;
type SharedGuard = RwLockReadGuard<'this, T>;
}
#[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
unsafe impl<T> Lock for RwLock<T> {
fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
self.write().unwrap()
}
fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
self.read().unwrap()
}
}
}
mod bounds {
#[allow(missing_debug_implementations)]
pub struct Bounds<T>(T);
pub trait Sealed {}
impl<T> Sealed for Bounds<T> {}
}