Skip to content

Commit 150da37

Browse files
authored
Unrolled build for rust-lang#135684
Rollup merge of rust-lang#135684 - ranger-ross:mutex-docs, r=joboet docs: Documented Send and Sync requirements for Mutex + MutexGuard This an attempt to continue where rust-lang#123225 left off. I did some light clean up from the work done in that PR. I also documented the `!Send` + `Sync` implementations for `MutexGuard` to the best of my knowledge. Let me know if I got anything wrong 😄 fixes rust-lang#122856 cc: ``@IoaNNUwU`` r? ``@joboet``
2 parents e08cd3c + 3d84a49 commit 150da37

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

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

+30-2
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,29 @@ pub struct Mutex<T: ?Sized> {
181181
data: UnsafeCell<T>,
182182
}
183183

184-
// these are the only places where `T: Send` matters; all other
185-
// functionality works fine on a single thread.
184+
/// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
185+
/// the owned `T` from the `Mutex` via [`into_inner`].
186+
///
187+
/// [`into_inner`]: Mutex::into_inner
186188
#[stable(feature = "rust1", since = "1.0.0")]
187189
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
190+
191+
/// `T` must be `Send` for [`Mutex`] to be `Sync`.
192+
/// This ensures that the protected data can be accessed safely from multiple threads
193+
/// without causing data races or other unsafe behavior.
194+
///
195+
/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
196+
/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
197+
/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
198+
/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
199+
/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
200+
/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
201+
/// to potential data races.
202+
///
203+
/// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
204+
/// to one thread at a time if `T` is not `Sync`.
205+
///
206+
/// [`Rc`]: crate::rc::Rc
188207
#[stable(feature = "rust1", since = "1.0.0")]
189208
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
190209

@@ -211,8 +230,17 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
211230
poison: poison::Guard,
212231
}
213232

233+
/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
234+
///
235+
/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
236+
/// release mutex locks on the same thread they were acquired.
237+
/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
238+
/// another thread.
214239
#[stable(feature = "rust1", since = "1.0.0")]
215240
impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
241+
242+
/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
243+
/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
216244
#[stable(feature = "mutexguard", since = "1.19.0")]
217245
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
218246

0 commit comments

Comments
 (0)