@@ -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
@@ -83,9 +103,18 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
83
103
lock : & ' a Mutex < T > ,
84
104
}
85
105
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.
86
112
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
87
113
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" ) ]
89
118
unsafe impl < T : ?Sized + Sync > Sync for MutexGuard < ' _ , T > { }
90
119
91
120
/// 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> {}
110
139
#[ must_not_suspend = "holding a MappedMutexGuard across suspend \
111
140
points can cause deadlocks, delays, \
112
141
and cause Futures to not implement `Send`"]
142
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
113
143
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
114
144
#[ clippy:: has_significant_drop]
115
145
pub struct MappedMutexGuard < ' a , T : ?Sized + ' a > {
@@ -122,8 +152,10 @@ pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
122
152
_variance : PhantomData < & ' a mut T > ,
123
153
}
124
154
155
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
125
156
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
126
157
impl < T : ?Sized > !Send for MappedMutexGuard < ' _ , T > { }
158
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
127
159
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
128
160
unsafe impl < T : ?Sized + Sync > Sync for MappedMutexGuard < ' _ , T > { }
129
161
@@ -143,6 +175,8 @@ impl<T> Mutex<T> {
143
175
pub const fn new ( t : T ) -> Mutex < T > {
144
176
Mutex { inner : sys:: Mutex :: new ( ) , data : UnsafeCell :: new ( t) }
145
177
}
178
+
179
+ // TODO(connor): Add `lock_value_accessors` feature methods.
146
180
}
147
181
148
182
impl < T : ?Sized > Mutex < T > {
@@ -198,6 +232,9 @@ impl<T: ?Sized> Mutex<T> {
198
232
/// If the mutex could not be acquired because it is already locked, then
199
233
/// this call will return [`None`].
200
234
///
235
+ /// TODO(connor): This should return a `TryLockResult` as specified in
236
+ /// <https://github.com/rust-lang/rust/issues/134645>
237
+ ///
201
238
/// # Examples
202
239
///
203
240
/// ```
@@ -235,7 +272,6 @@ impl<T: ?Sized> Mutex<T> {
235
272
/// assert_eq!(mutex.into_inner(), 0);
236
273
/// ```
237
274
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
238
- #[ inline]
239
275
pub fn into_inner ( self ) -> T
240
276
where
241
277
T : Sized ,
@@ -259,10 +295,11 @@ impl<T: ?Sized> Mutex<T> {
259
295
/// assert_eq!(*mutex.lock(), 10);
260
296
/// ```
261
297
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
262
- #[ inline]
263
298
pub fn get_mut ( & mut self ) -> & mut T {
264
299
self . data . get_mut ( )
265
300
}
301
+
302
+ // TODO(connor): Add `mutex_data_ptr` feature method.
266
303
}
267
304
268
305
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
@@ -330,14 +367,14 @@ impl<T: ?Sized> Drop for MutexGuard<'_, T> {
330
367
}
331
368
}
332
369
333
- #[ stable ( feature = "std_debug " , since = "1.16.0 " ) ]
370
+ #[ unstable ( feature = "nonpoison_mutex " , issue = "134645 " ) ]
334
371
impl < T : ?Sized + fmt:: Debug > fmt:: Debug for MutexGuard < ' _ , T > {
335
372
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
336
373
fmt:: Debug :: fmt ( & * * self , f)
337
374
}
338
375
}
339
376
340
- #[ stable ( feature = "std_guard_impls " , since = "1.20.0 " ) ]
377
+ #[ unstable ( feature = "nonpoison_mutex " , issue = "134645 " ) ]
341
378
impl < T : ?Sized + fmt:: Display > fmt:: Display for MutexGuard < ' _ , T > {
342
379
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
343
380
( * * self ) . fmt ( f)
@@ -353,6 +390,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
353
390
/// This is an associated function that needs to be used as
354
391
/// `MutexGuard::map(...)`. A method would interfere with methods of the
355
392
/// same name on the contents of the `MutexGuard` used through `Deref`.
393
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
356
394
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
357
395
pub fn map < U , F > ( orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
358
396
where
@@ -378,6 +416,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
378
416
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
379
417
/// same name on the contents of the `MutexGuard` used through `Deref`.
380
418
#[ doc( alias = "filter_map" ) ]
419
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
381
420
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
382
421
pub fn try_map < U , F > ( orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
383
422
where
@@ -399,6 +438,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
399
438
}
400
439
}
401
440
441
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
402
442
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
403
443
impl < T : ?Sized > Deref for MappedMutexGuard < ' _ , T > {
404
444
type Target = T ;
@@ -408,13 +448,15 @@ impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
408
448
}
409
449
}
410
450
451
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
411
452
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
412
453
impl < T : ?Sized > DerefMut for MappedMutexGuard < ' _ , T > {
413
454
fn deref_mut ( & mut self ) -> & mut T {
414
455
unsafe { self . data . as_mut ( ) }
415
456
}
416
457
}
417
458
459
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
418
460
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
419
461
impl < T : ?Sized > Drop for MappedMutexGuard < ' _ , T > {
420
462
#[ inline]
@@ -425,13 +467,15 @@ impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
425
467
}
426
468
}
427
469
470
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
428
471
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
429
472
impl < T : ?Sized + fmt:: Debug > fmt:: Debug for MappedMutexGuard < ' _ , T > {
430
473
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
431
474
fmt:: Debug :: fmt ( & * * self , f)
432
475
}
433
476
}
434
477
478
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
435
479
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
436
480
impl < T : ?Sized + fmt:: Display > fmt:: Display for MappedMutexGuard < ' _ , T > {
437
481
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -448,6 +492,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
448
492
/// This is an associated function that needs to be used as
449
493
/// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
450
494
/// same name on the contents of the `MutexGuard` used through `Deref`.
495
+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
451
496
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
452
497
pub fn map < U , F > ( mut orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
453
498
where
0 commit comments