Skip to content

Commit 5533606

Browse files
committed
Add MappedMutexGuard and MappedRwLock*Guard tests.
1 parent 20fa3a0 commit 5533606

File tree

2 files changed

+133
-2
lines changed

2 files changed

+133
-2
lines changed

Diff for: library/std/src/sync/mutex/tests.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::sync::atomic::{AtomicUsize, Ordering};
22
use crate::sync::mpsc::channel;
3-
use crate::sync::{Arc, Condvar, Mutex};
3+
use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard};
44
use crate::thread;
55

66
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
@@ -188,6 +188,21 @@ fn test_mutex_arc_poison() {
188188
assert!(arc.is_poisoned());
189189
}
190190

191+
#[test]
192+
fn test_mutex_arc_poison_mapped() {
193+
let arc = Arc::new(Mutex::new(1));
194+
assert!(!arc.is_poisoned());
195+
let arc2 = arc.clone();
196+
let _ = thread::spawn(move || {
197+
let lock = arc2.lock().unwrap();
198+
let lock = MutexGuard::map(lock, |val| val);
199+
assert_eq!(*lock, 2); // deliberate assertion failure to poison the mutex
200+
})
201+
.join();
202+
assert!(arc.lock().is_err());
203+
assert!(arc.is_poisoned());
204+
}
205+
191206
#[test]
192207
fn test_mutex_arc_nested() {
193208
// Tests nested mutexes and access
@@ -236,3 +251,16 @@ fn test_mutex_unsized() {
236251
let comp: &[i32] = &[4, 2, 5];
237252
assert_eq!(&*mutex.lock().unwrap(), comp);
238253
}
254+
255+
#[test]
256+
fn test_mapping_mapped_guard() {
257+
let arr = [0; 4];
258+
let mut lock = Mutex::new(arr);
259+
let guard = lock.lock().unwrap();
260+
let guard = MutexGuard::map(guard, |arr| &mut arr[..2]);
261+
let mut guard = MappedMutexGuard::map(guard, |slice| &mut slice[1..]);
262+
assert_eq!(guard.len(), 1);
263+
guard[0] = 42;
264+
drop(guard);
265+
assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]);
266+
}

Diff for: library/std/src/sync/rwlock/tests.rs

+104-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::sync::atomic::{AtomicUsize, Ordering};
22
use crate::sync::mpsc::channel;
3-
use crate::sync::{Arc, RwLock, RwLockReadGuard, TryLockError};
3+
use crate::sync::{
4+
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
5+
TryLockError,
6+
};
47
use crate::thread;
58
use rand::Rng;
69

@@ -55,6 +58,19 @@ fn test_rw_arc_poison_wr() {
5558
assert!(arc.read().is_err());
5659
}
5760

61+
#[test]
62+
fn test_rw_arc_poison_mapped_w_r() {
63+
let arc = Arc::new(RwLock::new(1));
64+
let arc2 = arc.clone();
65+
let _: Result<(), _> = thread::spawn(move || {
66+
let lock = arc2.write().unwrap();
67+
let _lock = RwLockWriteGuard::map(lock, |val| val);
68+
panic!();
69+
})
70+
.join();
71+
assert!(arc.read().is_err());
72+
}
73+
5874
#[test]
5975
fn test_rw_arc_poison_ww() {
6076
let arc = Arc::new(RwLock::new(1));
@@ -69,6 +85,20 @@ fn test_rw_arc_poison_ww() {
6985
assert!(arc.is_poisoned());
7086
}
7187

88+
#[test]
89+
fn test_rw_arc_poison_mapped_w_w() {
90+
let arc = Arc::new(RwLock::new(1));
91+
let arc2 = arc.clone();
92+
let _: Result<(), _> = thread::spawn(move || {
93+
let lock = arc2.write().unwrap();
94+
let _lock = RwLockWriteGuard::map(lock, |val| val);
95+
panic!();
96+
})
97+
.join();
98+
assert!(arc.write().is_err());
99+
assert!(arc.is_poisoned());
100+
}
101+
72102
#[test]
73103
fn test_rw_arc_no_poison_rr() {
74104
let arc = Arc::new(RwLock::new(1));
@@ -81,6 +111,21 @@ fn test_rw_arc_no_poison_rr() {
81111
let lock = arc.read().unwrap();
82112
assert_eq!(*lock, 1);
83113
}
114+
115+
#[test]
116+
fn test_rw_arc_no_poison_mapped_r_r() {
117+
let arc = Arc::new(RwLock::new(1));
118+
let arc2 = arc.clone();
119+
let _: Result<(), _> = thread::spawn(move || {
120+
let lock = arc2.read().unwrap();
121+
let _lock = RwLockReadGuard::map(lock, |val| val);
122+
panic!();
123+
})
124+
.join();
125+
let lock = arc.read().unwrap();
126+
assert_eq!(*lock, 1);
127+
}
128+
84129
#[test]
85130
fn test_rw_arc_no_poison_rw() {
86131
let arc = Arc::new(RwLock::new(1));
@@ -94,6 +139,20 @@ fn test_rw_arc_no_poison_rw() {
94139
assert_eq!(*lock, 1);
95140
}
96141

142+
#[test]
143+
fn test_rw_arc_no_poison_mapped_r_w() {
144+
let arc = Arc::new(RwLock::new(1));
145+
let arc2 = arc.clone();
146+
let _: Result<(), _> = thread::spawn(move || {
147+
let lock = arc2.read().unwrap();
148+
let _lock = RwLockReadGuard::map(lock, |val| val);
149+
panic!();
150+
})
151+
.join();
152+
let lock = arc.write().unwrap();
153+
assert_eq!(*lock, 1);
154+
}
155+
97156
#[test]
98157
fn test_rw_arc() {
99158
let arc = Arc::new(RwLock::new(0));
@@ -179,6 +238,16 @@ fn test_rwlock_try_write() {
179238
}
180239

181240
drop(read_guard);
241+
let mapped_read_guard = RwLockReadGuard::map(lock.read().unwrap(), |_| &());
242+
243+
let write_result = lock.try_write();
244+
match write_result {
245+
Err(TryLockError::WouldBlock) => (),
246+
Ok(_) => assert!(false, "try_write should not succeed while mapped_read_guard is in scope"),
247+
Err(_) => assert!(false, "unexpected error"),
248+
}
249+
250+
drop(mapped_read_guard);
182251
}
183252

184253
#[test]
@@ -257,3 +326,37 @@ fn test_read_guard_covariance() {
257326
}
258327
drop(lock);
259328
}
329+
330+
#[test]
331+
fn test_mapped_read_guard_covariance() {
332+
fn do_stuff<'a>(_: MappedRwLockReadGuard<'_, &'a i32>, _: &'a i32) {}
333+
let j: i32 = 5;
334+
let lock = RwLock::new((&j, &j));
335+
{
336+
let i = 6;
337+
let guard = lock.read().unwrap();
338+
let guard = RwLockReadGuard::map(guard, |(val, _val)| val);
339+
do_stuff(guard, &i);
340+
}
341+
drop(lock);
342+
}
343+
344+
#[test]
345+
fn test_mapping_mapped_guard() {
346+
let arr = [0; 4];
347+
let mut lock = RwLock::new(arr);
348+
let guard = lock.write().unwrap();
349+
let guard = RwLockWriteGuard::map(guard, |arr| &mut arr[..2]);
350+
let mut guard = MappedRwLockWriteGuard::map(guard, |slice| &mut slice[1..]);
351+
assert_eq!(guard.len(), 1);
352+
guard[0] = 42;
353+
drop(guard);
354+
assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]);
355+
356+
let guard = lock.read().unwrap();
357+
let guard = RwLockReadGuard::map(guard, |arr| &arr[..2]);
358+
let guard = MappedRwLockReadGuard::map(guard, |slice| &slice[1..]);
359+
assert_eq!(*guard, [42]);
360+
drop(guard);
361+
assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]);
362+
}

0 commit comments

Comments
 (0)