From a61983f9359724c5ffabb5c0a2525aca756fe9ea Mon Sep 17 00:00:00 2001 From: Jonathan Reem Date: Fri, 5 Feb 2016 02:22:32 -0800 Subject: [PATCH] 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 --- src/libstd/sync/mutex.rs | 61 +--------------------------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index e83ebd1061284..5ea0a3d7142f4 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(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::(mutex2.lock().unwrap(), |_| panic!()); - }).join().unwrap_err(); - - match mutex.lock() { - Ok(r) => panic!("Lock on poisioned Mutex is Ok: {:?}", &*r), - Err(_) => {} - }; - } }