mirror of
https://github.com/rust-lang/rust.git
synced 2025-11-25 13:58:31 +00:00
Rollup merge of #147328 - EFanZh:lock-with, r=joboet
Implement non-poisoning `Mutex::with_mut`, `RwLock::with` and `RwLock::with_mut` ACP: https://github.com/rust-lang/libs-team/issues/497.
This commit is contained in:
commit
56c96aebfc
@ -376,6 +376,40 @@ impl<T: ?Sized> Mutex<T> {
|
||||
pub const fn data_ptr(&self) -> *mut T {
|
||||
self.data.get()
|
||||
}
|
||||
|
||||
/// Acquires the mutex and provides mutable access to the underlying data by passing
|
||||
/// a mutable reference to the given closure.
|
||||
///
|
||||
/// This method acquires the lock, calls the provided closure with a mutable reference
|
||||
/// to the data, and returns the result of the closure. The lock is released after
|
||||
/// the closure completes, even if it panics.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(lock_value_accessors, nonpoison_mutex)]
|
||||
///
|
||||
/// use std::sync::nonpoison::Mutex;
|
||||
///
|
||||
/// let mutex = Mutex::new(2);
|
||||
///
|
||||
/// let result = mutex.with_mut(|data| {
|
||||
/// *data += 3;
|
||||
///
|
||||
/// *data + 5
|
||||
/// });
|
||||
///
|
||||
/// assert_eq!(*mutex.lock(), 5);
|
||||
/// assert_eq!(result, 10);
|
||||
/// ```
|
||||
#[unstable(feature = "lock_value_accessors", issue = "133407")]
|
||||
// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
|
||||
pub fn with_mut<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut T) -> R,
|
||||
{
|
||||
f(&mut self.lock())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
|
||||
|
||||
@ -498,6 +498,68 @@ impl<T: ?Sized> RwLock<T> {
|
||||
pub const fn data_ptr(&self) -> *mut T {
|
||||
self.data.get()
|
||||
}
|
||||
|
||||
/// Locks this `RwLock` with shared read access to the underlying data by passing
|
||||
/// a reference to the given closure.
|
||||
///
|
||||
/// This method acquires the lock, calls the provided closure with a reference
|
||||
/// to the data, and returns the result of the closure. The lock is released after
|
||||
/// the closure completes, even if it panics.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(lock_value_accessors, nonpoison_rwlock)]
|
||||
///
|
||||
/// use std::sync::nonpoison::RwLock;
|
||||
///
|
||||
/// let rwlock = RwLock::new(2);
|
||||
/// let result = rwlock.with(|data| *data + 3);
|
||||
///
|
||||
/// assert_eq!(result, 5);
|
||||
/// ```
|
||||
#[unstable(feature = "lock_value_accessors", issue = "133407")]
|
||||
// #[unstable(feature = "nonpoison_rwlock", issue = "134645")]
|
||||
pub fn with<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&T) -> R,
|
||||
{
|
||||
f(&self.read())
|
||||
}
|
||||
|
||||
/// Locks this `RwLock` with exclusive write access to the underlying data by passing
|
||||
/// a mutable reference to the given closure.
|
||||
///
|
||||
/// This method acquires the lock, calls the provided closure with a mutable reference
|
||||
/// to the data, and returns the result of the closure. The lock is released after
|
||||
/// the closure completes, even if it panics.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(lock_value_accessors, nonpoison_rwlock)]
|
||||
///
|
||||
/// use std::sync::nonpoison::RwLock;
|
||||
///
|
||||
/// let rwlock = RwLock::new(2);
|
||||
///
|
||||
/// let result = rwlock.with_mut(|data| {
|
||||
/// *data += 3;
|
||||
///
|
||||
/// *data + 5
|
||||
/// });
|
||||
///
|
||||
/// assert_eq!(*rwlock.read(), 5);
|
||||
/// assert_eq!(result, 10);
|
||||
/// ```
|
||||
#[unstable(feature = "lock_value_accessors", issue = "133407")]
|
||||
// #[unstable(feature = "nonpoison_rwlock", issue = "134645")]
|
||||
pub fn with_mut<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut T) -> R,
|
||||
{
|
||||
f(&mut self.write())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "nonpoison_rwlock", issue = "134645")]
|
||||
|
||||
@ -549,3 +549,17 @@ fn panic_while_mapping_unlocked_poison() {
|
||||
|
||||
drop(lock);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutex_with_mut() {
|
||||
let mutex = std::sync::nonpoison::Mutex::new(2);
|
||||
|
||||
let result = mutex.with_mut(|value| {
|
||||
*value += 3;
|
||||
|
||||
*value + 5
|
||||
});
|
||||
|
||||
assert_eq!(*mutex.lock(), 5);
|
||||
assert_eq!(result, 10);
|
||||
}
|
||||
|
||||
@ -861,3 +861,25 @@ fn panic_while_mapping_write_unlocked_poison() {
|
||||
|
||||
drop(lock);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rwlock_with() {
|
||||
let rwlock = std::sync::nonpoison::RwLock::new(2);
|
||||
let result = rwlock.with(|value| *value + 3);
|
||||
|
||||
assert_eq!(result, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rwlock_with_mut() {
|
||||
let rwlock = std::sync::nonpoison::RwLock::new(2);
|
||||
|
||||
let result = rwlock.with_mut(|value| {
|
||||
*value += 3;
|
||||
|
||||
*value + 5
|
||||
});
|
||||
|
||||
assert_eq!(*rwlock.read(), 5);
|
||||
assert_eq!(result, 10);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user