about summary refs log tree commit diff
path: root/library/std/src/sys_common
diff options
context:
space:
mode:
authorThe8472 <git@infinite-source.de>2021-03-14 19:10:34 +0100
committerThe8472 <git@infinite-source.de>2021-03-14 19:10:34 +0100
commite22143c075c7aee0a3a5bc90b51adff6cd250b34 (patch)
tree0437dc1abc8a47b16a66b475ef3fd90511a053bb /library/std/src/sys_common
parent9320b121b5b20d2201c9f5ec40fb3c241fcac6f0 (diff)
downloadrust-e22143c075c7aee0a3a5bc90b51adff6cd250b34.tar.gz
rust-e22143c075c7aee0a3a5bc90b51adff6cd250b34.zip
Revert "Revert "use RWlock when accessing os::env #81850""
This reverts commit acdca316c3d42299d31c1b47eb792006ffdfc29c.
Diffstat (limited to 'library/std/src/sys_common')
-rw-r--r--library/std/src/sys_common/rwlock.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
index 3705d641a1b..70b31b19f82 100644
--- a/library/std/src/sys_common/rwlock.rs
+++ b/library/std/src/sys_common/rwlock.rs
@@ -86,3 +86,62 @@ impl RWLock {
         self.0.destroy()
     }
 }
+
+// the cfg annotations only exist due to dead code warnings. the code itself is portable
+#[cfg(unix)]
+pub struct StaticRWLock(RWLock);
+
+#[cfg(unix)]
+impl StaticRWLock {
+    pub const fn new() -> StaticRWLock {
+        StaticRWLock(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_with_guard(&'static self) -> RWLockReadGuard {
+        // SAFETY: All methods require static references, therefore self
+        // cannot be moved between invocations.
+        unsafe {
+            self.0.read();
+        }
+        RWLockReadGuard(&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_with_guard(&'static self) -> RWLockWriteGuard {
+        // SAFETY: All methods require static references, therefore self
+        // cannot be moved between invocations.
+        unsafe {
+            self.0.write();
+        }
+        RWLockWriteGuard(&self.0)
+    }
+}
+
+#[cfg(unix)]
+pub struct RWLockReadGuard(&'static RWLock);
+
+#[cfg(unix)]
+impl Drop for RWLockReadGuard {
+    fn drop(&mut self) {
+        unsafe { self.0.read_unlock() }
+    }
+}
+
+#[cfg(unix)]
+pub struct RWLockWriteGuard(&'static RWLock);
+
+#[cfg(unix)]
+impl Drop for RWLockWriteGuard {
+    fn drop(&mut self) {
+        unsafe { self.0.write_unlock() }
+    }
+}