diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2023-08-31 12:50:44 +0200 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2023-09-07 13:04:23 +0200 |
| commit | c5996b80beaba54502fa86583b48cd6980b17b18 (patch) | |
| tree | ef26a4468e70f96e01664e16444a3cf464a4af5c /compiler/rustc_data_structures/src/sync | |
| parent | f00c1399987c60b4e884afc42f4aa6226855e9ae (diff) | |
| download | rust-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.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] |
