about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src/sync
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2023-08-31 12:50:44 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2023-09-07 13:04:23 +0200
commitc5996b80beaba54502fa86583b48cd6980b17b18 (patch)
treeef26a4468e70f96e01664e16444a3cf464a4af5c /compiler/rustc_data_structures/src/sync
parentf00c1399987c60b4e884afc42f4aa6226855e9ae (diff)
downloadrust-c5996b80beaba54502fa86583b48cd6980b17b18.tar.gz
rust-c5996b80beaba54502fa86583b48cd6980b17b18.zip
Use `Freeze` for `SourceFile.external_src`
Diffstat (limited to 'compiler/rustc_data_structures/src/sync')
-rw-r--r--compiler/rustc_data_structures/src/sync/freeze.rs47
1 files changed, 44 insertions, 3 deletions
diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs
index d9f1d72d851..88c710e5236 100644
--- a/compiler/rustc_data_structures/src/sync/freeze.rs
+++ b/compiler/rustc_data_structures/src/sync/freeze.rs
@@ -27,7 +27,26 @@ unsafe impl<T: DynSync + DynSend> DynSync for FreezeLock<T> {}
 impl<T> FreezeLock<T> {
     #[inline]
     pub fn new(value: T) -> Self {
-        Self { data: UnsafeCell::new(value), frozen: AtomicBool::new(false), lock: RwLock::new(()) }
+        Self::with(value, false)
+    }
+
+    #[inline]
+    pub fn frozen(value: T) -> Self {
+        Self::with(value, true)
+    }
+
+    #[inline]
+    pub fn with(value: T, frozen: bool) -> Self {
+        Self {
+            data: UnsafeCell::new(value),
+            frozen: AtomicBool::new(frozen),
+            lock: RwLock::new(()),
+        }
+    }
+
+    #[inline]
+    pub fn is_frozen(&self) -> bool {
+        self.frozen.load(Ordering::Acquire)
     }
 
     #[inline]
@@ -43,12 +62,25 @@ impl<T> FreezeLock<T> {
     }
 
     #[inline]
+    pub fn borrow(&self) -> FreezeReadGuard<'_, T> {
+        self.read()
+    }
+
+    #[inline]
     #[track_caller]
     pub fn write(&self) -> FreezeWriteGuard<'_, T> {
+        self.try_write().expect("still mutable")
+    }
+
+    #[inline]
+    pub fn try_write(&self) -> Option<FreezeWriteGuard<'_, T>> {
         let _lock_guard = self.lock.write();
         // Use relaxed ordering since we're in the write lock.
-        assert!(!self.frozen.load(Ordering::Relaxed), "still mutable");
-        FreezeWriteGuard { _lock_guard, lock: self, marker: PhantomData }
+        if self.frozen.load(Ordering::Relaxed) {
+            None
+        } else {
+            Some(FreezeWriteGuard { _lock_guard, lock: self, marker: PhantomData })
+        }
     }
 
     #[inline]
@@ -90,6 +122,15 @@ pub struct FreezeWriteGuard<'a, T> {
     marker: PhantomData<&'a mut T>,
 }
 
+impl<'a, T> FreezeWriteGuard<'a, T> {
+    pub fn freeze(self) -> &'a T {
+        self.lock.frozen.store(true, Ordering::Release);
+
+        // SAFETY: This is frozen so the data cannot be modified and shared access is sound.
+        unsafe { &*self.lock.data.get() }
+    }
+}
+
 impl<'a, T: 'a> Deref for FreezeWriteGuard<'a, T> {
     type Target = T;
     #[inline]