Skip to content

Commit 068039b

Browse files
committed
docs: Documented Send and Sync requirements for Mutex + MutexGuard
1 parent 8e59cf9 commit 068039b

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,24 @@ 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+
/// Mutex is a container that wraps `T`, so it's necessary for `T` to be `Send`
185+
/// to safely send `Mutex` to another thread. This ensures that the protected
186+
/// data can be accessed safely from multiple threads without causing data races
187+
/// or other unsafe behavior.
188+
///
189+
/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
190+
/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
191+
/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
192+
/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
193+
/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
194+
/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
195+
/// to potential data races.
186196
#[stable(feature = "rust1", since = "1.0.0")]
187197
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
198+
199+
/// [`Mutex`] can be `Sync` even if its inner type `T` is not `Sync` itself.
200+
/// This is because [`Mutex`] provides a safe interface for accessing `T` through
201+
/// locking mechanisms, ensuring that only one thread can access `T` at a time.
188202
#[stable(feature = "rust1", since = "1.0.0")]
189203
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
190204

@@ -211,8 +225,18 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
211225
poison: poison::Guard,
212226
}
213227

228+
/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
229+
/// On platforms that use POSIX thread (commonly referred to as pthreads) there is a requirement to
230+
/// release mutex locks on the same thread they were acquired.
231+
/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
232+
/// another thread.
214233
#[stable(feature = "rust1", since = "1.0.0")]
215234
impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
235+
236+
/// A [`MutexGuard`] can be `Sync` even though it is not `Send` because ownership is not transfer to
237+
/// a new thread. Because ownership always stays on the original thread `Sync`
238+
/// is safe to implement for [`MutexGuard`].
239+
/// See the `!Send` implementation on [`MutexGuard`] for more details.
216240
#[stable(feature = "mutexguard", since = "1.19.0")]
217241
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
218242

0 commit comments

Comments
 (0)