blob: ba56f3a8f1b5263b5a46d84848b27f702b7b3b90 [file] [log] [blame]
use crate::sys::locks as imp;
/// An OS-based reader-writer lock, meant for use in static variables.
///
/// This rwlock does not implement poisoning.
///
/// This rwlock has a const constructor ([`StaticRwLock::new`]), does not
/// implement `Drop` to cleanup resources.
pub struct StaticRwLock(imp::RwLock);
impl StaticRwLock {
/// Creates a new rwlock for use.
#[inline]
pub const fn new() -> Self {
Self(imp::RwLock::new())
}
/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn read(&'static self) -> StaticRwLockReadGuard {
unsafe { self.0.read() };
StaticRwLockReadGuard(&self.0)
}
/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn write(&'static self) -> StaticRwLockWriteGuard {
unsafe { self.0.write() };
StaticRwLockWriteGuard(&self.0)
}
}
#[must_use]
pub struct StaticRwLockReadGuard(&'static imp::RwLock);
impl Drop for StaticRwLockReadGuard {
#[inline]
fn drop(&mut self) {
unsafe {
self.0.read_unlock();
}
}
}
#[must_use]
pub struct StaticRwLockWriteGuard(&'static imp::RwLock);
impl Drop for StaticRwLockWriteGuard {
#[inline]
fn drop(&mut self) {
unsafe {
self.0.write_unlock();
}
}
}
/// An OS-based reader-writer lock.
///
/// This rwlock cleans up its resources in its `Drop` implementation and may
/// safely be moved (when not borrowed).
///
/// This rwlock does not implement poisoning.
///
/// This is either a wrapper around `LazyBox<imp::RwLock>` or `imp::RwLock`,
/// depending on the platform. It is boxed on platforms where `imp::RwLock` may
/// not be moved.
pub struct MovableRwLock(imp::MovableRwLock);
impl MovableRwLock {
/// Creates a new reader-writer lock for use.
#[inline]
pub const fn new() -> Self {
Self(imp::MovableRwLock::new())
}
/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
#[inline]
pub fn read(&self) {
unsafe { self.0.read() }
}
/// Attempts to acquire shared access to this lock, returning whether it
/// succeeded or not.
///
/// This function does not block the current thread.
#[inline]
pub fn try_read(&self) -> bool {
unsafe { self.0.try_read() }
}
/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
#[inline]
pub fn write(&self) {
unsafe { self.0.write() }
}
/// Attempts to acquire exclusive access to this lock, returning whether it
/// succeeded or not.
///
/// This function does not block the current thread.
#[inline]
pub fn try_write(&self) -> bool {
unsafe { self.0.try_write() }
}
/// Unlocks previously acquired shared access to this lock.
///
/// Behavior is undefined if the current thread does not have shared access.
#[inline]
pub unsafe fn read_unlock(&self) {
self.0.read_unlock()
}
/// Unlocks previously acquired exclusive access to this lock.
///
/// Behavior is undefined if the current thread does not currently have
/// exclusive access.
#[inline]
pub unsafe fn write_unlock(&self) {
self.0.write_unlock()
}
}