@@ -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" ) ]
5253pub 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" ) ]
6063unsafe 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" ) ]
6282unsafe 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" ) ]
87113impl < 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" ) ]
89118unsafe 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]
115145pub 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" ) ]
126157impl < T : ?Sized > !Send for MappedMutexGuard < ' _ , T > { }
158+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
127159#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
128160unsafe 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
148182impl < 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 " ) ]
334371impl < 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 " ) ]
341378impl < 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" ) ]
403443impl < 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" ) ]
412453impl < 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" ) ]
419461impl < 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" ) ]
429472impl < 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" ) ]
436480impl < 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