Skip to content

Commit deda5c5

Browse files
committed
update nonpoison mutex
This commit brings the `mutex.rs` file more in line with the current `poison/mutex.rs` file. Additionally, it ensures that all items are marked with `#[unstable(feature = "nonpoison_mutex", issue = "134645")]`. Some features that are currently unstable on nightly also have the "nonpoison_mutex" feature, but they have their correct feature gates commented out above. Not all of the current nightly features are implemented here, and that will happen in a later commit. Note that this commit is likely not to pass CI.
1 parent 76bcc93 commit deda5c5

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

library/std/src/sync/nonpoison/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
//! Non-poisoning syncronous locks.
1+
//! Non-poisoning synchronous locks.
22
//!
3-
//! The locks found on this module will not become poisoned when a thread panics whilst holding a guard.
3+
//! The difference from the locks in the [`poison`] module is that the locks in this module will not
4+
//! become poisoned when a thread panics while holding a guard.
45
56
#[unstable(feature = "sync_nonpoison", issue = "134645")]
67
pub use self::mutex::MappedMutexGuard;

library/std/src/sync/nonpoison/mutex.rs

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::sys::sync as sys;
88

99
/// A mutual exclusion primitive useful for protecting shared data.
1010
///
11-
/// For more information about mutexes, check out the documentation for the
12-
/// poisoning variant of this lock found at [std::sync::poison::Mutex](crate::sync::poison::Mutex).
11+
/// For more information about mutexes, check out the documentation for the poisoning variant of
12+
/// this lock (which can be found at [`poison::Mutex`])
1313
///
1414
/// # Example
1515
///
@@ -47,17 +47,37 @@ use crate::sys::sync as sys;
4747
/// rx.recv().unwrap();
4848
/// ```
4949
///
50+
/// [`poison::Mutex`]: crate::sync::poison::Mutex
5051
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
5152
#[cfg_attr(not(test), rustc_diagnostic_item = "NonPoisonMutex")]
5253
pub struct Mutex<T: ?Sized> {
5354
inner: sys::Mutex,
5455
data: UnsafeCell<T>,
5556
}
5657

57-
// these are the only places where `T: Send` matters; all other
58-
// functionality works fine on a single thread.
58+
/// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
59+
/// the owned `T` from the `Mutex` via [`into_inner`].
60+
///
61+
/// [`into_inner`]: Mutex::into_inner
5962
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
6063
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
64+
65+
/// `T` must be `Send` for [`Mutex`] to be `Sync`.
66+
/// This ensures that the protected data can be accessed safely from multiple threads
67+
/// without causing data races or other unsafe behavior.
68+
///
69+
/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
70+
/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
71+
/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
72+
/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
73+
/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
74+
/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
75+
/// to potential data races.
76+
///
77+
/// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
78+
/// to one thread at a time if `T` is not `Sync`.
79+
///
80+
/// [`Rc`]: crate::rc::Rc
6181
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
6282
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
6383

@@ -110,6 +130,7 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
110130
#[must_not_suspend = "holding a MappedMutexGuard across suspend \
111131
points can cause deadlocks, delays, \
112132
and cause Futures to not implement `Send`"]
133+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
113134
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
114135
#[clippy::has_significant_drop]
115136
pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
@@ -122,8 +143,10 @@ pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
122143
_variance: PhantomData<&'a mut T>,
123144
}
124145

146+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
125147
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
126148
impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {}
149+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
127150
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
128151
unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
129152

@@ -143,6 +166,8 @@ impl<T> Mutex<T> {
143166
pub const fn new(t: T) -> Mutex<T> {
144167
Mutex { inner: sys::Mutex::new(), data: UnsafeCell::new(t) }
145168
}
169+
170+
// TODO(connor): Add `lock_value_accessors` feature methods.
146171
}
147172

148173
impl<T: ?Sized> Mutex<T> {
@@ -197,6 +222,9 @@ impl<T: ?Sized> Mutex<T> {
197222
///
198223
/// If the mutex could not be acquired because it is already locked, then
199224
/// this call will return [`None`].
225+
///
226+
/// TODO(connor): This should return a `TryLockResult` as specified in
227+
/// <https://github.com/rust-lang/rust/issues/134645>
200228
///
201229
/// # Examples
202230
///
@@ -235,7 +263,6 @@ impl<T: ?Sized> Mutex<T> {
235263
/// assert_eq!(mutex.into_inner(), 0);
236264
/// ```
237265
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
238-
#[inline]
239266
pub fn into_inner(self) -> T
240267
where
241268
T: Sized,
@@ -259,10 +286,11 @@ impl<T: ?Sized> Mutex<T> {
259286
/// assert_eq!(*mutex.lock(), 10);
260287
/// ```
261288
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
262-
#[inline]
263289
pub fn get_mut(&mut self) -> &mut T {
264290
self.data.get_mut()
265291
}
292+
293+
// TODO(connor): Add `mutex_data_ptr` feature method.
266294
}
267295

268296
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
@@ -330,14 +358,14 @@ impl<T: ?Sized> Drop for MutexGuard<'_, T> {
330358
}
331359
}
332360

333-
#[stable(feature = "std_debug", since = "1.16.0")]
361+
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
334362
impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
335363
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336364
fmt::Debug::fmt(&**self, f)
337365
}
338366
}
339367

340-
#[stable(feature = "std_guard_impls", since = "1.20.0")]
368+
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
341369
impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
342370
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343371
(**self).fmt(f)
@@ -353,6 +381,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
353381
/// This is an associated function that needs to be used as
354382
/// `MutexGuard::map(...)`. A method would interfere with methods of the
355383
/// same name on the contents of the `MutexGuard` used through `Deref`.
384+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
356385
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
357386
pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
358387
where
@@ -378,6 +407,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
378407
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
379408
/// same name on the contents of the `MutexGuard` used through `Deref`.
380409
#[doc(alias = "filter_map")]
410+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
381411
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
382412
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
383413
where
@@ -399,6 +429,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
399429
}
400430
}
401431

432+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
402433
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
403434
impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
404435
type Target = T;
@@ -408,13 +439,15 @@ impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
408439
}
409440
}
410441

442+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
411443
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
412444
impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
413445
fn deref_mut(&mut self) -> &mut T {
414446
unsafe { self.data.as_mut() }
415447
}
416448
}
417449

450+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
418451
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
419452
impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
420453
#[inline]
@@ -425,13 +458,15 @@ impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
425458
}
426459
}
427460

461+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
428462
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
429463
impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
430464
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
431465
fmt::Debug::fmt(&**self, f)
432466
}
433467
}
434468

469+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
435470
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
436471
impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
437472
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -448,6 +483,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
448483
/// This is an associated function that needs to be used as
449484
/// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
450485
/// same name on the contents of the `MutexGuard` used through `Deref`.
486+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
451487
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
452488
pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
453489
where

0 commit comments

Comments
 (0)