diff --git a/tokio/src/sync/rwlock.rs b/tokio/src/sync/rwlock.rs index a84c4c123af..750765fb49b 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, diff --git a/tokio/src/sync/tests/loom_rwlock.rs b/tokio/src/sync/tests/loom_rwlock.rs index 48d06e1d5f6..2834a26356c 100644 --- a/tokio/src/sync/tests/loom_rwlock.rs +++ b/tokio/src/sync/tests/loom_rwlock.rs @@ -6,7 +6,7 @@ use std::sync::Arc; #[test] fn concurrent_write() { - let mut b = loom::model::Builder::new(); + let b = loom::model::Builder::new(); b.check(|| { let rwlock = Arc::new(RwLock::::new(0)); @@ -37,7 +37,7 @@ fn concurrent_write() { #[test] fn concurrent_read_write() { - let mut b = loom::model::Builder::new(); + let b = loom::model::Builder::new(); b.check(|| { let rwlock = Arc::new(RwLock::::new(0)); @@ -76,3 +76,24 @@ fn concurrent_read_write() { assert_eq!(10, *guard); }); } +#[test] +fn downgrade() { + loom::model(|| { + let lock = Arc::new(RwLock::new(1)); + + let n = block_on(lock.write()); + + let cloned_lock = lock.clone(); + let handle = thread::spawn(move || { + let mut guard = block_on(cloned_lock.write()); + *guard = 2; + }); + + let n = n.downgrade(); + assert_eq!(*n, 1); + + drop(n); + handle.join().unwrap(); + assert_eq!(*block_on(lock.read()), 2); + }); +} diff --git a/tokio/src/sync/tests/mod.rs b/tokio/src/sync/tests/mod.rs index a78be6f3e15..c5d5601961d 100644 --- a/tokio/src/sync/tests/mod.rs +++ b/tokio/src/sync/tests/mod.rs @@ -12,4 +12,5 @@ cfg_loom! { mod loom_oneshot; mod loom_semaphore_batch; mod loom_watch; + mod loom_rwlock; }