diff options
author | Zahari Dichev <zaharidichev@gmail.com> | 2020-10-23 20:07:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-23 10:07:00 -0700 |
commit | e804f88d60071f0d89db85aaa4a073857904b545 (patch) | |
tree | 2450fdc093b9f361573febc7f7ca22b0275ae1c6 /tokio/src/sync/rwlock.rs | |
parent | c1539132110d3f8d20d22efb4b3f6a16fafd0e63 (diff) |
sync: add mem::forget to RwLockWriteGuard::downgrade. (#2957)
Currently when `RwLockWriteGuard::downgrade` the `MAX_READS - 1`
permits are added to the semaphore. When `RwLockWriteGuard::drop`
gets invoked however another `MAX_READS` permits are added. This
results in releasing more permits that were actually aquired when
downgrading a write to a read lock. This is why we need to call
`mem::forget` on the `RwLockWriteGuard` in order to avoid
invoking the destructor.
Fixes: #2941
Diffstat (limited to 'tokio/src/sync/rwlock.rs')
-rw-r--r-- | tokio/src/sync/rwlock.rs | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/tokio/src/sync/rwlock.rs b/tokio/src/sync/rwlock.rs index a84c4c12..750765fb 100644 --- a/tokio/src/sync/rwlock.rs +++ b/tokio/src/sync/rwlock.rs @@ -375,8 +375,6 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { /// let n = n.downgrade(); /// assert_eq!(*n, 1, "downgrade is atomic"); /// - /// assert_eq!(*lock.read().await, 1, "additional readers can obtain locks"); - /// /// drop(n); /// handle.await.unwrap(); /// assert_eq!(*lock.read().await, 2, "second writer obtained write lock"); @@ -389,7 +387,8 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { // Release all but one of the permits held by the write guard s.release(MAX_READS - 1); - + // NB: Forget to avoid drop impl from being called. + mem::forget(self); RwLockReadGuard { s, data, |