diff options
Diffstat (limited to 'compiler/rustc_data_structures/src/sync/freeze.rs')
| -rw-r--r-- | compiler/rustc_data_structures/src/sync/freeze.rs | 47 |
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] |
