Skip to content

Commit f283875

Browse files
committed
std::sync::RwLock docs improvement
1 parent 14039a4 commit f283875

File tree

1 file changed

+120
-13
lines changed

1 file changed

+120
-13
lines changed

src/libstd/sync/rwlock.rs

+120-13
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,24 @@ use sys_common::rwlock as sys;
2424
/// of the underlying data (exclusive access) and the read portion of this lock
2525
/// typically allows for read-only access (shared access).
2626
///
27+
/// In comparison, a [`Mutex`] does not distinguish between readers or writers
28+
/// that aquire the lock, therefore blocking any threads waiting for the lock to
29+
/// become available. An `RwLock` will allow any number of readers to aquire the
30+
/// lock as long as a writer is not holding the lock.
31+
///
2732
/// The priority policy of the lock is dependent on the underlying operating
2833
/// system's implementation, and this type does not guarantee that any
2934
/// particular policy will be used.
3035
///
3136
/// The type parameter `T` represents the data that this lock protects. It is
32-
/// required that `T` satisfies `Send` to be shared across threads and `Sync` to
33-
/// allow concurrent access through readers. The RAII guards returned from the
34-
/// locking methods implement `Deref` (and `DerefMut` for the `write` methods)
35-
/// to allow access to the contained of the lock.
37+
/// required that `T` satisfies [`Send`] to be shared across threads and
38+
/// [`Sync`] to allow concurrent access through readers. The RAII guards
39+
/// returned from the locking methods implement [`Deref`][] (and [`DerefMut`]
40+
/// for the `write` methods) to allow access to the contained of the lock.
3641
///
3742
/// # Poisoning
3843
///
39-
/// An `RwLock`, like `Mutex`, will become poisoned on a panic. Note, however,
44+
/// An `RwLock`, like [`Mutex`], will become poisoned on a panic. Note, however,
4045
/// that an `RwLock` may only be poisoned if a panic occurs while it is locked
4146
/// exclusively (write mode). If a panic occurs in any reader, then the lock
4247
/// will not be poisoned.
@@ -63,6 +68,12 @@ use sys_common::rwlock as sys;
6368
/// assert_eq!(*w, 6);
6469
/// } // write lock is dropped here
6570
/// ```
71+
///
72+
/// [`Deref`]: ../../std/ops/trait.Deref.html
73+
/// [`DerefMut`]: ../../std/ops/trait.DerefMut.html
74+
/// [`Send`]: ../../std/marker/trait.Send.html
75+
/// [`Sync`]: ../../std/marker/trait.Sync.html
76+
/// [`Mutex`]: struct.Mutex.html
6677
#[stable(feature = "rust1", since = "1.0.0")]
6778
pub struct RwLock<T: ?Sized> {
6879
inner: Box<sys::RWLock>,
@@ -154,6 +165,24 @@ impl<T: ?Sized> RwLock<T> {
154165
/// # Panics
155166
///
156167
/// This function might panic when called if the lock is already held by the current thread.
168+
///
169+
/// # Examples
170+
///
171+
/// ```
172+
/// use std::sync::{Arc, RwLock};
173+
/// use std::thread;
174+
///
175+
/// let lock = Arc::new(RwLock::new(1));
176+
/// let c_lock = lock.clone();
177+
///
178+
/// let n = lock.read().unwrap();
179+
/// assert_eq!(*n, 1);
180+
///
181+
/// thread::spawn(move || {
182+
/// let r = c_lock.read();
183+
/// assert!(r.is_ok());
184+
/// }).join().unwrap();
185+
/// ```
157186
#[inline]
158187
#[stable(feature = "rust1", since = "1.0.0")]
159188
pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
@@ -180,6 +209,19 @@ impl<T: ?Sized> RwLock<T> {
180209
/// is poisoned whenever a writer panics while holding an exclusive lock. An
181210
/// error will only be returned if the lock would have otherwise been
182211
/// acquired.
212+
///
213+
/// # Examples
214+
///
215+
/// ```
216+
/// use std::sync::RwLock;
217+
///
218+
/// let lock = RwLock::new(1);
219+
///
220+
/// match lock.try_read() {
221+
/// Ok(n) => assert_eq!(*n, 1),
222+
/// Err(_) => unreachable!(),
223+
/// };
224+
/// ```
183225
#[inline]
184226
#[stable(feature = "rust1", since = "1.0.0")]
185227
pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
@@ -210,6 +252,19 @@ impl<T: ?Sized> RwLock<T> {
210252
/// # Panics
211253
///
212254
/// This function might panic when called if the lock is already held by the current thread.
255+
///
256+
/// # Examples
257+
///
258+
/// ```
259+
/// use std::sync::RwLock;
260+
///
261+
/// let lock = RwLock::new(1);
262+
///
263+
/// let mut n = lock.write().unwrap();
264+
/// *n = 2;
265+
///
266+
/// assert!(lock.try_read().is_err());
267+
/// ```
213268
#[inline]
214269
#[stable(feature = "rust1", since = "1.0.0")]
215270
pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
@@ -236,6 +291,19 @@ impl<T: ?Sized> RwLock<T> {
236291
/// is poisoned whenever a writer panics while holding an exclusive lock. An
237292
/// error will only be returned if the lock would have otherwise been
238293
/// acquired.
294+
///
295+
/// # Examples
296+
///
297+
/// ```
298+
/// use std::sync::RwLock;
299+
///
300+
/// let lock = RwLock::new(1);
301+
///
302+
/// let n = lock.read().unwrap();
303+
/// assert_eq!(*n, 1);
304+
///
305+
/// assert!(lock.try_write().is_err());
306+
/// ```
239307
#[inline]
240308
#[stable(feature = "rust1", since = "1.0.0")]
241309
pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
@@ -253,6 +321,22 @@ impl<T: ?Sized> RwLock<T> {
253321
/// If another thread is active, the lock can still become poisoned at any
254322
/// time. You should not trust a `false` value for program correctness
255323
/// without additional synchronization.
324+
///
325+
/// # Examples
326+
///
327+
/// ```
328+
/// use std::sync::{Arc, RwLock};
329+
/// use std::thread;
330+
///
331+
/// let lock = Arc::new(RwLock::new(0));
332+
/// let c_lock = lock.clone();
333+
///
334+
/// let _ = thread::spawn(move || {
335+
/// let _lock = c_lock.write().unwrap();
336+
/// panic!(); // the lock gets poisoned
337+
/// }).join();
338+
/// assert_eq!(lock.is_poisoned(), true);
339+
/// ```
256340
#[inline]
257341
#[stable(feature = "sync_poison", since = "1.2.0")]
258342
pub fn is_poisoned(&self) -> bool {
@@ -267,6 +351,19 @@ impl<T: ?Sized> RwLock<T> {
267351
/// is poisoned whenever a writer panics while holding an exclusive lock. An
268352
/// error will only be returned if the lock would have otherwise been
269353
/// acquired.
354+
///
355+
/// # Examples
356+
///
357+
/// ```
358+
/// use std::sync::RwLock;
359+
///
360+
/// let lock = RwLock::new(String::new());
361+
/// {
362+
/// let mut s = lock.write().unwrap();
363+
/// *s = "modified".to_owned();
364+
/// }
365+
/// assert_eq!(lock.into_inner().unwrap(), "modified");
366+
/// ```
270367
#[stable(feature = "rwlock_into_inner", since = "1.6.0")]
271368
pub fn into_inner(self) -> LockResult<T> where T: Sized {
272369
// We know statically that there are no outstanding references to
@@ -282,7 +379,7 @@ impl<T: ?Sized> RwLock<T> {
282379
(ptr::read(inner), ptr::read(poison), ptr::read(data))
283380
};
284381
mem::forget(self);
285-
inner.destroy(); // Keep in sync with the `Drop` impl.
382+
inner.destroy(); // Keep in sync with the `Drop` impl.
286383
drop(inner);
287384

288385
poison::map_result(poison.borrow(), |_| data.into_inner())
@@ -300,6 +397,16 @@ impl<T: ?Sized> RwLock<T> {
300397
/// is poisoned whenever a writer panics while holding an exclusive lock. An
301398
/// error will only be returned if the lock would have otherwise been
302399
/// acquired.
400+
///
401+
/// # Examples
402+
///
403+
/// ```
404+
/// use std::sync::RwLock;
405+
///
406+
/// let mut lock = RwLock::new(0);
407+
/// *lock.get_mut().unwrap() = 10;
408+
/// assert_eq!(*lock.read().unwrap(), 10);
409+
/// ```
303410
#[stable(feature = "rwlock_get_mut", since = "1.6.0")]
304411
pub fn get_mut(&mut self) -> LockResult<&mut T> {
305412
// We know statically that there are no other references to `self`, so
@@ -486,7 +593,7 @@ mod tests {
486593
fn test_rw_arc_poison_wr() {
487594
let arc = Arc::new(RwLock::new(1));
488595
let arc2 = arc.clone();
489-
let _: Result<(), _> = thread::spawn(move|| {
596+
let _: Result<(), _> = thread::spawn(move || {
490597
let _lock = arc2.write().unwrap();
491598
panic!();
492599
}).join();
@@ -498,7 +605,7 @@ mod tests {
498605
let arc = Arc::new(RwLock::new(1));
499606
assert!(!arc.is_poisoned());
500607
let arc2 = arc.clone();
501-
let _: Result<(), _> = thread::spawn(move|| {
608+
let _: Result<(), _> = thread::spawn(move || {
502609
let _lock = arc2.write().unwrap();
503610
panic!();
504611
}).join();
@@ -510,7 +617,7 @@ mod tests {
510617
fn test_rw_arc_no_poison_rr() {
511618
let arc = Arc::new(RwLock::new(1));
512619
let arc2 = arc.clone();
513-
let _: Result<(), _> = thread::spawn(move|| {
620+
let _: Result<(), _> = thread::spawn(move || {
514621
let _lock = arc2.read().unwrap();
515622
panic!();
516623
}).join();
@@ -521,7 +628,7 @@ mod tests {
521628
fn test_rw_arc_no_poison_rw() {
522629
let arc = Arc::new(RwLock::new(1));
523630
let arc2 = arc.clone();
524-
let _: Result<(), _> = thread::spawn(move|| {
631+
let _: Result<(), _> = thread::spawn(move || {
525632
let _lock = arc2.read().unwrap();
526633
panic!()
527634
}).join();
@@ -535,7 +642,7 @@ mod tests {
535642
let arc2 = arc.clone();
536643
let (tx, rx) = channel();
537644

538-
thread::spawn(move|| {
645+
thread::spawn(move || {
539646
let mut lock = arc2.write().unwrap();
540647
for _ in 0..10 {
541648
let tmp = *lock;
@@ -550,7 +657,7 @@ mod tests {
550657
let mut children = Vec::new();
551658
for _ in 0..5 {
552659
let arc3 = arc.clone();
553-
children.push(thread::spawn(move|| {
660+
children.push(thread::spawn(move || {
554661
let lock = arc3.read().unwrap();
555662
assert!(*lock >= 0);
556663
}));
@@ -571,7 +678,7 @@ mod tests {
571678
fn test_rw_arc_access_in_unwind() {
572679
let arc = Arc::new(RwLock::new(1));
573680
let arc2 = arc.clone();
574-
let _ = thread::spawn(move|| -> () {
681+
let _ = thread::spawn(move || -> () {
575682
struct Unwinder {
576683
i: Arc<RwLock<isize>>,
577684
}

0 commit comments

Comments
 (0)