From e804f88d60071f0d89db85aaa4a073857904b545 Mon Sep 17 00:00:00 2001 From: Zahari Dichev Date: Fri, 23 Oct 2020 20:07:00 +0300 Subject: 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 --- tokio/src/sync/rwlock.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tokio/src/sync/rwlock.rs') 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, -- cgit v1.2.3