Open
Description
RwLock::try_upgradeable_read()
is
pub fn try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T, R>> {
if self.lock.fetch_or(UPGRADED, Ordering::Acquire) & (WRITER | UPGRADED) == 0 {
Some(RwLockUpgradableGuard {
phantom: PhantomData,
inner: self,
data: unsafe { &*self.data.get() },
})
} else {
// We can't unflip the UPGRADED bit back just yet as there is another upgradeable or write lock.
// When they unlock, they will clear the bit.
None
}
}
RwLockUpgradableGuard::try_upgrade_internal()
contains compare_exchange( &inner.lock, UPGRADED, WRITER, Ordering::Acquire, Ordering::Relaxed,strong )
which clears UPGRADED
and sets WRITER
.
If try_upgrade_internal()
is called then UPGRADED
is cleared and WRITER
is set. If try_upgradeable_read()
is called on another thread this will set UPGRADED
and return None
, as it mentions in the fail branch it cant clear UPGRADED
and the owner of the lock must clear it. However a number of debug assertions particularly in RwLockWriteGuard::downgrade_to_upgradeable
and RwLockUpgradableGuard::drop()
will panic in this event, even though RwLockWriteGuard::downgrade_to_upgradeable
clears both UPGRADED
and WRITER
Metadata
Assignees
Labels
No labels