Skip to content

Commit

Permalink
Merge pull request #431 from mbyzhang/master
Browse files Browse the repository at this point in the history
Fix panic when calling `with_upgraded` twice on a `ArcRwLockUpgradableReadGuard`
  • Loading branch information
Amanieu committed Mar 12, 2024
2 parents cd7bda0 + 1bb45aa commit 66d025b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
12 changes: 6 additions & 6 deletions lock_api/src/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2168,7 +2168,7 @@ impl<'a, R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade + 'a, T: ?Sized +
if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } {
// Safety: We just upgraded the lock, so we have mutable access to the data.
// This will restore the state the lock was in at the start of the function.
defer!(unsafe { self.rwlock.raw.downgrade_upgradable() });
defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });

// Safety: We upgraded the lock, so we have mutable access to the data.
// When this function returns, whether by drop or panic,
Expand Down Expand Up @@ -2199,7 +2199,7 @@ impl<'a, R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade + 'a, T: ?Sized +
if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } {
// Safety: We just upgraded the lock, so we have mutable access to the data.
// This will restore the state the lock was in at the start of the function.
defer!(unsafe { self.rwlock.raw.downgrade_upgradable() });
defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });

// Safety: We upgraded the lock, so we have mutable access to the data.
// When this function returns, whether by drop or panic,
Expand Down Expand Up @@ -2412,7 +2412,7 @@ impl<R: RawRwLockUpgradeDowngrade, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T>

// Safety: We just upgraded the lock, so we have mutable access to the data.
// This will restore the state the lock was in at the start of the function.
defer!(unsafe { self.rwlock.raw.downgrade_upgradable() });
defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });

// Safety: We upgraded the lock, so we have mutable access to the data.
// When this function returns, whether by drop or panic,
Expand All @@ -2434,7 +2434,7 @@ impl<R: RawRwLockUpgradeDowngrade, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T>
if unsafe { self.rwlock.raw.try_upgrade() } {
// Safety: We just upgraded the lock, so we have mutable access to the data.
// This will restore the state the lock was in at the start of the function.
defer!(unsafe { self.rwlock.raw.downgrade_upgradable() });
defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });

// Safety: We upgraded the lock, so we have mutable access to the data.
// When this function returns, whether by drop or panic,
Expand Down Expand Up @@ -2522,7 +2522,7 @@ impl<R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade, T: ?Sized>
if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } {
// Safety: We just upgraded the lock, so we have mutable access to the data.
// This will restore the state the lock was in at the start of the function.
defer!(unsafe { self.rwlock.raw.downgrade_upgradable() });
defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });

// Safety: We upgraded the lock, so we have mutable access to the data.
// When this function returns, whether by drop or panic,
Expand Down Expand Up @@ -2553,7 +2553,7 @@ impl<R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade, T: ?Sized>
if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } {
// Safety: We just upgraded the lock, so we have mutable access to the data.
// This will restore the state the lock was in at the start of the function.
defer!(unsafe { self.rwlock.raw.downgrade_upgradable() });
defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });

// Safety: We upgraded the lock, so we have mutable access to the data.
// When this function returns, whether by drop or panic,
Expand Down
18 changes: 18 additions & 0 deletions src/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,4 +638,22 @@ mod tests {
assert!(lock.is_locked_exclusive());
}
}

#[test]
#[cfg(feature = "arc_lock")]
fn test_issue_430() {
let lock = std::sync::Arc::new(RwLock::new(0));

let mut rl = lock.upgradable_read_arc();

rl.with_upgraded(|_| {
println!("lock upgrade");
});

rl.with_upgraded(|_| {
println!("lock upgrade");
});

drop(lock);
}
}

0 comments on commit 66d025b

Please sign in to comment.