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:
parent
8fe90966e1
commit
67c18fdec5
4 changed files with 70 additions and 73 deletions
|
@ -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>>);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue