diff options
| author | Zachary S <zasample18+github@gmail.com> | 2023-10-24 13:32:53 -0500 |
|---|---|---|
| committer | Zachary S <zasample18+github@gmail.com> | 2023-12-05 17:30:36 -0600 |
| commit | 5533606fe0def63a62a3f75be4eb2d87081a05c4 (patch) | |
| tree | 4ee549b4e04b6f89899d8a06d5aa22d4b7e49315 | |
| parent | 20fa3a0d8f529b428eeacf7cce184345f200654d (diff) | |
| download | rust-5533606fe0def63a62a3f75be4eb2d87081a05c4.tar.gz rust-5533606fe0def63a62a3f75be4eb2d87081a05c4.zip | |
Add MappedMutexGuard and MappedRwLock*Guard tests.
| -rw-r--r-- | library/std/src/sync/mutex/tests.rs | 30 | ||||
| -rw-r--r-- | library/std/src/sync/rwlock/tests.rs | 105 |
2 files changed, 133 insertions, 2 deletions
diff --git a/library/std/src/sync/mutex/tests.rs b/library/std/src/sync/mutex/tests.rs index 1786a3c09ff..cf69813baa3 100644 --- a/library/std/src/sync/mutex/tests.rs +++ b/library/std/src/sync/mutex/tests.rs @@ -1,6 +1,6 @@ use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::mpsc::channel; -use crate::sync::{Arc, Condvar, Mutex}; +use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard}; use crate::thread; struct Packet<T>(Arc<(Mutex<T>, Condvar)>); @@ -189,6 +189,21 @@ fn test_mutex_arc_poison() { } #[test] +fn test_mutex_arc_poison_mapped() { + let arc = Arc::new(Mutex::new(1)); + assert!(!arc.is_poisoned()); + let arc2 = arc.clone(); + let _ = thread::spawn(move || { + let lock = arc2.lock().unwrap(); + let lock = MutexGuard::map(lock, |val| val); + assert_eq!(*lock, 2); // deliberate assertion failure to poison the mutex + }) + .join(); + assert!(arc.lock().is_err()); + assert!(arc.is_poisoned()); +} + +#[test] fn test_mutex_arc_nested() { // Tests nested mutexes and access // to underlying data. @@ -236,3 +251,16 @@ fn test_mutex_unsized() { let comp: &[i32] = &[4, 2, 5]; assert_eq!(&*mutex.lock().unwrap(), comp); } + +#[test] +fn test_mapping_mapped_guard() { + let arr = [0; 4]; + let mut lock = Mutex::new(arr); + let guard = lock.lock().unwrap(); + let guard = MutexGuard::map(guard, |arr| &mut arr[..2]); + let mut guard = MappedMutexGuard::map(guard, |slice| &mut slice[1..]); + assert_eq!(guard.len(), 1); + guard[0] = 42; + drop(guard); + assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]); +} diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs index 1a9d3d3f12f..0a5eb7aac02 100644 --- a/library/std/src/sync/rwlock/tests.rs +++ b/library/std/src/sync/rwlock/tests.rs @@ -1,6 +1,9 @@ use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::mpsc::channel; -use crate::sync::{Arc, RwLock, RwLockReadGuard, TryLockError}; +use crate::sync::{ + Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, + TryLockError, +}; use crate::thread; use rand::Rng; @@ -56,6 +59,19 @@ fn test_rw_arc_poison_wr() { } #[test] +fn test_rw_arc_poison_mapped_w_r() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let lock = arc2.write().unwrap(); + let _lock = RwLockWriteGuard::map(lock, |val| val); + panic!(); + }) + .join(); + assert!(arc.read().is_err()); +} + +#[test] fn test_rw_arc_poison_ww() { let arc = Arc::new(RwLock::new(1)); assert!(!arc.is_poisoned()); @@ -70,6 +86,20 @@ fn test_rw_arc_poison_ww() { } #[test] +fn test_rw_arc_poison_mapped_w_w() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let lock = arc2.write().unwrap(); + let _lock = RwLockWriteGuard::map(lock, |val| val); + panic!(); + }) + .join(); + assert!(arc.write().is_err()); + assert!(arc.is_poisoned()); +} + +#[test] fn test_rw_arc_no_poison_rr() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -81,6 +111,21 @@ fn test_rw_arc_no_poison_rr() { let lock = arc.read().unwrap(); assert_eq!(*lock, 1); } + +#[test] +fn test_rw_arc_no_poison_mapped_r_r() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let lock = arc2.read().unwrap(); + let _lock = RwLockReadGuard::map(lock, |val| val); + panic!(); + }) + .join(); + let lock = arc.read().unwrap(); + assert_eq!(*lock, 1); +} + #[test] fn test_rw_arc_no_poison_rw() { let arc = Arc::new(RwLock::new(1)); @@ -95,6 +140,20 @@ fn test_rw_arc_no_poison_rw() { } #[test] +fn test_rw_arc_no_poison_mapped_r_w() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let lock = arc2.read().unwrap(); + let _lock = RwLockReadGuard::map(lock, |val| val); + panic!(); + }) + .join(); + let lock = arc.write().unwrap(); + assert_eq!(*lock, 1); +} + +#[test] fn test_rw_arc() { let arc = Arc::new(RwLock::new(0)); let arc2 = arc.clone(); @@ -179,6 +238,16 @@ fn test_rwlock_try_write() { } drop(read_guard); + let mapped_read_guard = RwLockReadGuard::map(lock.read().unwrap(), |_| &()); + + let write_result = lock.try_write(); + match write_result { + Err(TryLockError::WouldBlock) => (), + Ok(_) => assert!(false, "try_write should not succeed while mapped_read_guard is in scope"), + Err(_) => assert!(false, "unexpected error"), + } + + drop(mapped_read_guard); } #[test] @@ -257,3 +326,37 @@ fn test_read_guard_covariance() { } drop(lock); } + +#[test] +fn test_mapped_read_guard_covariance() { + fn do_stuff<'a>(_: MappedRwLockReadGuard<'_, &'a i32>, _: &'a i32) {} + let j: i32 = 5; + let lock = RwLock::new((&j, &j)); + { + let i = 6; + let guard = lock.read().unwrap(); + let guard = RwLockReadGuard::map(guard, |(val, _val)| val); + do_stuff(guard, &i); + } + drop(lock); +} + +#[test] +fn test_mapping_mapped_guard() { + let arr = [0; 4]; + let mut lock = RwLock::new(arr); + let guard = lock.write().unwrap(); + let guard = RwLockWriteGuard::map(guard, |arr| &mut arr[..2]); + let mut guard = MappedRwLockWriteGuard::map(guard, |slice| &mut slice[1..]); + assert_eq!(guard.len(), 1); + guard[0] = 42; + drop(guard); + assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]); + + let guard = lock.read().unwrap(); + let guard = RwLockReadGuard::map(guard, |arr| &arr[..2]); + let guard = MappedRwLockReadGuard::map(guard, |slice| &slice[1..]); + assert_eq!(*guard, [42]); + drop(guard); + assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]); +} |
