// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![unstable(feature = "reentrant_mutex", reason = "new API")]
+
+#![unstable(feature = "reentrant_mutex", reason = "new API",
+ issue = "27738")]
use prelude::v1::*;
/// dropped (falls out of scope), the lock will be unlocked.
///
/// The data protected by the mutex can be accessed through this guard via its
-/// Deref and DerefMut implementations
+/// Deref implementation.
+///
+/// # Mutability
+///
+/// Unlike `MutexGuard`, `ReentrantMutexGuard` does not implement `DerefMut`,
+/// because implementation of the trait would violate Rust’s reference aliasing
+/// rules. Use interior mutability (usually `RefCell`) in order to mutate the
+/// guarded data.
#[must_use]
pub struct ReentrantMutexGuard<'a, T: 'a> {
- // funny underscores due to how Deref/DerefMut currently work (they
- // disregard field privacy).
+ // funny underscores due to how Deref currently works (it disregards field
+ // privacy).
__lock: &'a ReentrantMutex<T>,
__poison: poison::Guard,
}
data: t,
};
mutex.inner.init();
- return mutex
+ mutex
}
}
impl<'mutex, T> Deref for ReentrantMutexGuard<'mutex, T> {
type Target = T;
- fn deref<'a>(&'a self) -> &'a T {
+ fn deref(&self) -> &T {
&self.__lock.data
}
}
use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
use cell::RefCell;
use sync::Arc;
- use boxed;
use thread;
#[test]
#[test]
fn is_mutex() {
- let m = ReentrantMutex::new(RefCell::new(0));
+ let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
+ let m2 = m.clone();
let lock = m.lock().unwrap();
- let handle = thread::scoped(|| {
- let lock = m.lock().unwrap();
+ let child = thread::spawn(move || {
+ let lock = m2.lock().unwrap();
assert_eq!(*lock.borrow(), 4950);
});
for i in 0..100 {
*lock.borrow_mut() += i;
}
drop(lock);
- drop(handle);
+ child.join().unwrap();
}
#[test]
fn trylock_works() {
- let m = ReentrantMutex::new(());
- let lock = m.try_lock().unwrap();
- let lock2 = m.try_lock().unwrap();
- {
- thread::scoped(|| {
- let lock = m.try_lock();
- assert!(lock.is_err());
- });
- }
- let lock3 = m.try_lock().unwrap();
+ let m = Arc::new(ReentrantMutex::new(()));
+ let m2 = m.clone();
+ let _lock = m.try_lock().unwrap();
+ let _lock2 = m.try_lock().unwrap();
+ thread::spawn(move || {
+ let lock = m2.try_lock();
+ assert!(lock.is_err());
+ }).join().unwrap();
+ let _lock3 = m.try_lock().unwrap();
}
pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
*lock.borrow_mut() = 1;
let lock2 = mc.lock().unwrap();
*lock.borrow_mut() = 2;
- let answer = Answer(lock2);
+ let _answer = Answer(lock2);
panic!("What the answer to my lifetimes dilemma is?");
- drop(answer);
}).join();
assert!(result.is_err());
let r = m.lock().err().unwrap().into_inner();