summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys_common/rwlock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys_common/rwlock.rs')
-rw-r--r--library/std/src/sys_common/rwlock.rs130
1 files changed, 130 insertions, 0 deletions
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
new file mode 100644
index 000000000..ba56f3a8f
--- /dev/null
+++ b/library/std/src/sys_common/rwlock.rs
@@ -0,0 +1,130 @@
+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()
+ }
+}