@@ -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" ) ]
6778pub 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