Use Freeze
for SourceFile.external_src
This commit is contained in:
parent
f00c139998
commit
c5996b80be
8 changed files with 91 additions and 46 deletions
|
@ -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]
|
||||
|
@ -42,13 +61,26 @@ 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]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue