1
Fork 0

Use Pin for the 'don't move' requirement of ReentrantMutex.

The code in io::stdio before this change misused the ReentrantMutexes,
by calling init() on them and moving them afterwards. Now that
ReentrantMutex requires Pin for init(), this mistake is no longer easy
to make.
This commit is contained in:
Mara Bos 2020-10-10 20:20:14 +02:00
parent 8fe90966e1
commit 67c18fdec5
4 changed files with 70 additions and 73 deletions

View file

@ -1,4 +1,6 @@
use crate::boxed::Box;
use crate::cell::RefCell;
use crate::pin::Pin;
use crate::sync::Arc;
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
use crate::thread;
@ -6,10 +8,11 @@ use crate::thread;
#[test]
fn smoke() {
let m = unsafe {
let m = ReentrantMutex::new(());
m.init();
let mut m = Box::pin(ReentrantMutex::new(()));
m.as_mut().init();
m
};
let m = m.as_ref();
{
let a = m.lock();
{
@ -27,18 +30,19 @@ fn smoke() {
#[test]
fn is_mutex() {
let m = unsafe {
let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
m.init();
m
// FIXME: Simplify this if Arc gets a Arc::get_pin_mut.
let mut m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
Pin::new_unchecked(Arc::get_mut_unchecked(&mut m)).init();
Pin::new_unchecked(m)
};
let m2 = m.clone();
let lock = m.lock();
let lock = m.as_ref().lock();
let child = thread::spawn(move || {
let lock = m2.lock();
let lock = m2.as_ref().lock();
assert_eq!(*lock.borrow(), 4950);
});
for i in 0..100 {
let lock = m.lock();
let lock = m.as_ref().lock();
*lock.borrow_mut() += i;
}
drop(lock);
@ -48,20 +52,21 @@ fn is_mutex() {
#[test]
fn trylock_works() {
let m = unsafe {
let m = Arc::new(ReentrantMutex::new(()));
m.init();
m
// FIXME: Simplify this if Arc gets a Arc::get_pin_mut.
let mut m = Arc::new(ReentrantMutex::new(()));
Pin::new_unchecked(Arc::get_mut_unchecked(&mut m)).init();
Pin::new_unchecked(m)
};
let m2 = m.clone();
let _lock = m.try_lock();
let _lock2 = m.try_lock();
let _lock = m.as_ref().try_lock();
let _lock2 = m.as_ref().try_lock();
thread::spawn(move || {
let lock = m2.try_lock();
let lock = m2.as_ref().try_lock();
assert!(lock.is_none());
})
.join()
.unwrap();
let _lock3 = m.try_lock();
let _lock3 = m.as_ref().try_lock();
}
pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);