@@ -8,8 +8,8 @@ use crate::sys::sync as sys;
8
8
9
9
/// A mutual exclusion primitive useful for protecting shared data.
10
10
///
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`])
13
13
///
14
14
/// # Example
15
15
///
@@ -47,17 +47,37 @@ use crate::sys::sync as sys;
47
47
/// rx.recv().unwrap();
48
48
/// ```
49
49
///
50
+ /// [`poison::Mutex`]: crate::sync::poison::Mutex
50
51
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
51
52
#[ cfg_attr( not( test) , rustc_diagnostic_item = "NonPoisonMutex" ) ]
52
53
pub struct Mutex < T : ?Sized > {
53
54
inner : sys:: Mutex ,
54
55
data : UnsafeCell < T > ,
55
56
}
56
57
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
59
62
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
60
63
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
61
81
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
62
82
unsafe impl < T : ?Sized + Send > Sync for Mutex < T > { }
63
83
@@ -110,6 +130,7 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
110
130
#[ must_not_suspend = "holding a MappedMutexGuard across suspend \
111
131
points can cause deadlocks, delays, \
112
132
and cause Futures to not implement `Send`"]
133
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
113
134
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
114
135
#[ clippy:: has_significant_drop]
115
136
pub struct MappedMutexGuard < ' a , T : ?Sized + ' a > {
@@ -122,8 +143,10 @@ pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
122
143
_variance : PhantomData < & ' a mut T > ,
123
144
}
124
145
146
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
125
147
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
126
148
impl < T : ?Sized > !Send for MappedMutexGuard < ' _ , T > { }
149
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
127
150
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
128
151
unsafe impl < T : ?Sized + Sync > Sync for MappedMutexGuard < ' _ , T > { }
129
152
@@ -143,6 +166,8 @@ impl<T> Mutex<T> {
143
166
pub const fn new ( t : T ) -> Mutex < T > {
144
167
Mutex { inner : sys:: Mutex :: new ( ) , data : UnsafeCell :: new ( t) }
145
168
}
169
+
170
+ // TODO(connor): Add `lock_value_accessors` feature methods.
146
171
}
147
172
148
173
impl < T : ?Sized > Mutex < T > {
@@ -197,6 +222,9 @@ impl<T: ?Sized> Mutex<T> {
197
222
///
198
223
/// If the mutex could not be acquired because it is already locked, then
199
224
/// 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>
200
228
///
201
229
/// # Examples
202
230
///
@@ -235,7 +263,6 @@ impl<T: ?Sized> Mutex<T> {
235
263
/// assert_eq!(mutex.into_inner(), 0);
236
264
/// ```
237
265
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
238
- #[ inline]
239
266
pub fn into_inner ( self ) -> T
240
267
where
241
268
T : Sized ,
@@ -259,10 +286,11 @@ impl<T: ?Sized> Mutex<T> {
259
286
/// assert_eq!(*mutex.lock(), 10);
260
287
/// ```
261
288
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
262
- #[ inline]
263
289
pub fn get_mut ( & mut self ) -> & mut T {
264
290
self . data . get_mut ( )
265
291
}
292
+
293
+ // TODO(connor): Add `mutex_data_ptr` feature method.
266
294
}
267
295
268
296
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
@@ -330,14 +358,14 @@ impl<T: ?Sized> Drop for MutexGuard<'_, T> {
330
358
}
331
359
}
332
360
333
- #[ stable ( feature = "std_debug " , since = "1.16.0 " ) ]
361
+ #[ unstable ( feature = "nonpoison_mutex " , issue = "134645 " ) ]
334
362
impl < T : ?Sized + fmt:: Debug > fmt:: Debug for MutexGuard < ' _ , T > {
335
363
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
336
364
fmt:: Debug :: fmt ( & * * self , f)
337
365
}
338
366
}
339
367
340
- #[ stable ( feature = "std_guard_impls " , since = "1.20.0 " ) ]
368
+ #[ unstable ( feature = "nonpoison_mutex " , issue = "134645 " ) ]
341
369
impl < T : ?Sized + fmt:: Display > fmt:: Display for MutexGuard < ' _ , T > {
342
370
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
343
371
( * * self ) . fmt ( f)
@@ -353,6 +381,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
353
381
/// This is an associated function that needs to be used as
354
382
/// `MutexGuard::map(...)`. A method would interfere with methods of the
355
383
/// same name on the contents of the `MutexGuard` used through `Deref`.
384
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
356
385
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
357
386
pub fn map < U , F > ( orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
358
387
where
@@ -378,6 +407,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
378
407
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
379
408
/// same name on the contents of the `MutexGuard` used through `Deref`.
380
409
#[ doc( alias = "filter_map" ) ]
410
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
381
411
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
382
412
pub fn try_map < U , F > ( orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
383
413
where
@@ -399,6 +429,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
399
429
}
400
430
}
401
431
432
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
402
433
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
403
434
impl < T : ?Sized > Deref for MappedMutexGuard < ' _ , T > {
404
435
type Target = T ;
@@ -408,13 +439,15 @@ impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
408
439
}
409
440
}
410
441
442
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
411
443
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
412
444
impl < T : ?Sized > DerefMut for MappedMutexGuard < ' _ , T > {
413
445
fn deref_mut ( & mut self ) -> & mut T {
414
446
unsafe { self . data . as_mut ( ) }
415
447
}
416
448
}
417
449
450
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
418
451
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
419
452
impl < T : ?Sized > Drop for MappedMutexGuard < ' _ , T > {
420
453
#[ inline]
@@ -425,13 +458,15 @@ impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
425
458
}
426
459
}
427
460
461
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
428
462
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
429
463
impl < T : ?Sized + fmt:: Debug > fmt:: Debug for MappedMutexGuard < ' _ , T > {
430
464
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
431
465
fmt:: Debug :: fmt ( & * * self , f)
432
466
}
433
467
}
434
468
469
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
435
470
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
436
471
impl < T : ?Sized + fmt:: Display > fmt:: Display for MappedMutexGuard < ' _ , T > {
437
472
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -448,6 +483,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
448
483
/// This is an associated function that needs to be used as
449
484
/// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
450
485
/// same name on the contents of the `MutexGuard` used through `Deref`.
486
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
451
487
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
452
488
pub fn map < U , F > ( mut orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
453
489
where
0 commit comments