diff options
| author | Jonathan Reem <jonathan.reem@gmail.com> | 2016-02-05 02:22:32 -0800 |
|---|---|---|
| committer | Jonathan Reem <jonathan.reem@gmail.com> | 2016-02-05 02:26:19 -0800 |
| commit | a61983f9359724c5ffabb5c0a2525aca756fe9ea (patch) | |
| tree | c6dec5d3f1cf4aea78fe2aea5b1e28796c63adf1 | |
| parent | 2ad6dc2556c19f49280b561fc1f5246ff9f9d6ed (diff) | |
| download | rust-a61983f9359724c5ffabb5c0a2525aca756fe9ea.tar.gz rust-a61983f9359724c5ffabb5c0a2525aca756fe9ea.zip | |
Remove MutexGuard::map, as it is not safe in combination with Condvar.
It could return in the future if it returned a different guard type, which could not be used with Condvar, otherwise it is unsafe as another thread can invalidate an "inner" reference during a Condvar::wait. cc #27746
| -rw-r--r-- | src/libstd/sync/mutex.rs | 61 |
1 files changed, 1 insertions, 60 deletions
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index e83ebd10612..5ea0a3d7142 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -387,50 +387,6 @@ impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> { } }) } - - /// Transform this guard to hold a sub-borrow of the original data. - /// - /// Applies the supplied closure to the data, returning a new lock - /// guard referencing the borrow returned by the closure. - /// - /// # Examples - /// - /// ```rust - /// # #![feature(guard_map)] - /// # use std::sync::{Mutex, MutexGuard}; - /// let x = Mutex::new(vec![1, 2]); - /// - /// { - /// let mut y = MutexGuard::map(x.lock().unwrap(), |v| &mut v[0]); - /// *y = 3; - /// } - /// - /// assert_eq!(&*x.lock().unwrap(), &[3, 2]); - /// ``` - #[unstable(feature = "guard_map", - reason = "recently added, needs RFC for stabilization", - issue = "27746")] - pub fn map<U: ?Sized, F>(this: Self, cb: F) -> MutexGuard<'mutex, U> - where F: FnOnce(&'mutex mut T) -> &'mutex mut U - { - // Compute the new data while still owning the original lock - // in order to correctly poison if the callback panics. - let data = unsafe { ptr::read(&this.__data) }; - let new_data = cb(data); - - // We don't want to unlock the lock by running the destructor of the - // original lock, so just read the fields we need and forget it. - let (poison, lock) = unsafe { - (ptr::read(&this.__poison), ptr::read(&this.__lock)) - }; - mem::forget(this); - - MutexGuard { - __lock: lock, - __data: new_data, - __poison: poison - } - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -469,7 +425,7 @@ mod tests { use prelude::v1::*; use sync::mpsc::channel; - use sync::{Arc, Mutex, StaticMutex, Condvar, MutexGuard}; + use sync::{Arc, Mutex, StaticMutex, Condvar}; use sync::atomic::{AtomicUsize, Ordering}; use thread; @@ -713,19 +669,4 @@ mod tests { let comp: &[i32] = &[4, 2, 5]; assert_eq!(&*mutex.lock().unwrap(), comp); } - - #[test] - fn test_mutex_guard_map_panic() { - let mutex = Arc::new(Mutex::new(vec![1, 2])); - let mutex2 = mutex.clone(); - - thread::spawn(move || { - let _ = MutexGuard::map::<usize, _>(mutex2.lock().unwrap(), |_| panic!()); - }).join().unwrap_err(); - - match mutex.lock() { - Ok(r) => panic!("Lock on poisioned Mutex is Ok: {:?}", &*r), - Err(_) => {} - }; - } } |
