Skip to content

Commit 40e06b4

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 will likely not pass CI.
1 parent 26d874c commit 40e06b4

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
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: 54 additions & 9 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

@@ -83,9 +103,18 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
83103
lock: &'a Mutex<T>,
84104
}
85105

106+
/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
107+
///
108+
/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
109+
/// release mutex locks on the same thread they were acquired.
110+
/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
111+
/// another thread.
86112
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
87113
impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
88-
#[stable(feature = "mutexguard", since = "1.19.0")]
114+
115+
/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
116+
/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
117+
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
89118
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
90119

91120
/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
@@ -110,6 +139,7 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
110139
#[must_not_suspend = "holding a MappedMutexGuard across suspend \
111140
points can cause deadlocks, delays, \
112141
and cause Futures to not implement `Send`"]
142+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
113143
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
114144
#[clippy::has_significant_drop]
115145
pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
@@ -122,8 +152,10 @@ pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
122152
_variance: PhantomData<&'a mut T>,
123153
}
124154

155+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
125156
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
126157
impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {}
158+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
127159
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
128160
unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
129161

@@ -143,6 +175,8 @@ impl<T> Mutex<T> {
143175
pub const fn new(t: T) -> Mutex<T> {
144176
Mutex { inner: sys::Mutex::new(), data: UnsafeCell::new(t) }
145177
}
178+
179+
// TODO(connor): Add `lock_value_accessors` feature methods.
146180
}
147181

148182
impl<T: ?Sized> Mutex<T> {
@@ -198,6 +232,9 @@ impl<T: ?Sized> Mutex<T> {
198232
/// If the mutex could not be acquired because it is already locked, then
199233
/// this call will return [`None`].
200234
///
235+
/// TODO(connor): This should return a `TryLockResult` as specified in
236+
/// <https://github.com/rust-lang/rust/issues/134645>
237+
///
201238
/// # Examples
202239
///
203240
/// ```
@@ -235,7 +272,6 @@ impl<T: ?Sized> Mutex<T> {
235272
/// assert_eq!(mutex.into_inner(), 0);
236273
/// ```
237274
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
238-
#[inline]
239275
pub fn into_inner(self) -> T
240276
where
241277
T: Sized,
@@ -259,10 +295,11 @@ impl<T: ?Sized> Mutex<T> {
259295
/// assert_eq!(*mutex.lock(), 10);
260296
/// ```
261297
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
262-
#[inline]
263298
pub fn get_mut(&mut self) -> &mut T {
264299
self.data.get_mut()
265300
}
301+
302+
// TODO(connor): Add `mutex_data_ptr` feature method.
266303
}
267304

268305
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
@@ -330,14 +367,14 @@ impl<T: ?Sized> Drop for MutexGuard<'_, T> {
330367
}
331368
}
332369

333-
#[stable(feature = "std_debug", since = "1.16.0")]
370+
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
334371
impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
335372
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336373
fmt::Debug::fmt(&**self, f)
337374
}
338375
}
339376

340-
#[stable(feature = "std_guard_impls", since = "1.20.0")]
377+
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
341378
impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
342379
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343380
(**self).fmt(f)
@@ -353,6 +390,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
353390
/// This is an associated function that needs to be used as
354391
/// `MutexGuard::map(...)`. A method would interfere with methods of the
355392
/// same name on the contents of the `MutexGuard` used through `Deref`.
393+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
356394
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
357395
pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
358396
where
@@ -378,6 +416,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
378416
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
379417
/// same name on the contents of the `MutexGuard` used through `Deref`.
380418
#[doc(alias = "filter_map")]
419+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
381420
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
382421
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
383422
where
@@ -399,6 +438,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
399438
}
400439
}
401440

441+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
402442
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
403443
impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
404444
type Target = T;
@@ -408,13 +448,15 @@ impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
408448
}
409449
}
410450

451+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
411452
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
412453
impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
413454
fn deref_mut(&mut self) -> &mut T {
414455
unsafe { self.data.as_mut() }
415456
}
416457
}
417458

459+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
418460
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
419461
impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
420462
#[inline]
@@ -425,13 +467,15 @@ impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
425467
}
426468
}
427469

470+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
428471
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
429472
impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
430473
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
431474
fmt::Debug::fmt(&**self, f)
432475
}
433476
}
434477

478+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
435479
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
436480
impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
437481
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -448,6 +492,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
448492
/// This is an associated function that needs to be used as
449493
/// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
450494
/// same name on the contents of the `MutexGuard` used through `Deref`.
495+
// #[unstable(feature = "mapped_lock_guards", issue = "117108")]
451496
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
452497
pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
453498
where

0 commit comments

Comments
 (0)