Skip to content

Commit e6378cb

Browse files
committed
Auto merge of #25153 - jgallagher:rwlock-try-write, r=alexcrichton
Previously, `try_write` actually only obtained shared read access (but would return a `RwLockWriteGuard` if that access was successful). Also updates the docs for `try_read` and `try_write`, which were leftover from when those methods returned `Option` instead of `Result`.
2 parents 0848d1c + 833fc27 commit e6378cb

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

src/libstd/sync/rwlock.rs

+36-12
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,16 @@ impl<T: ?Sized> RwLock<T> {
171171
RwLockReadGuard::new(&*self.inner, &self.data)
172172
}
173173

174-
/// Attempts to acquire this lock with shared read access.
174+
/// Attempts to acquire this rwlock with shared read access.
175+
///
176+
/// If the access could not be granted at this time, then `Err` is returned.
177+
/// Otherwise, an RAII guard is returned which will release the shared access
178+
/// when it is dropped.
175179
///
176-
/// This function will never block and will return immediately if `read`
177-
/// would otherwise succeed. Returns `Some` of an RAII guard which will
178-
/// release the shared access of this thread when dropped, or `None` if the
179-
/// access could not be granted. This method does not provide any
180-
/// guarantees with respect to the ordering of whether contentious readers
181-
/// or writers will acquire the lock first.
180+
/// This function does not block.
181+
///
182+
/// This function does not provide any guarantees with respect to the ordering
183+
/// of whether contentious readers or writers will acquire the lock first.
182184
///
183185
/// # Failure
184186
///
@@ -219,9 +221,14 @@ impl<T: ?Sized> RwLock<T> {
219221

220222
/// Attempts to lock this rwlock with exclusive write access.
221223
///
222-
/// This function does not ever block, and it will return `None` if a call
223-
/// to `write` would otherwise block. If successful, an RAII guard is
224-
/// returned.
224+
/// If the lock could not be acquired at this time, then `Err` is returned.
225+
/// Otherwise, an RAII guard is returned which will release the lock when
226+
/// it is dropped.
227+
///
228+
/// This function does not block.
229+
///
230+
/// This function does not provide any guarantees with respect to the ordering
231+
/// of whether contentious readers or writers will acquire the lock first.
225232
///
226233
/// # Failure
227234
///
@@ -232,7 +239,7 @@ impl<T: ?Sized> RwLock<T> {
232239
#[inline]
233240
#[stable(feature = "rust1", since = "1.0.0")]
234241
pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
235-
if unsafe { self.inner.lock.try_read() } {
242+
if unsafe { self.inner.lock.try_write() } {
236243
Ok(try!(RwLockWriteGuard::new(&*self.inner, &self.data)))
237244
} else {
238245
Err(TryLockError::WouldBlock)
@@ -413,7 +420,7 @@ mod tests {
413420
use rand::{self, Rng};
414421
use sync::mpsc::channel;
415422
use thread;
416-
use sync::{Arc, RwLock, StaticRwLock, RW_LOCK_INIT};
423+
use sync::{Arc, RwLock, StaticRwLock, TryLockError, RW_LOCK_INIT};
417424

418425
#[test]
419426
fn smoke() {
@@ -577,4 +584,21 @@ mod tests {
577584
let comp: &[i32] = &[4, 2, 5];
578585
assert_eq!(&*rw.read().unwrap(), comp);
579586
}
587+
588+
#[test]
589+
fn test_rwlock_try_write() {
590+
use mem::drop;
591+
592+
let lock = RwLock::new(0isize);
593+
let read_guard = lock.read().unwrap();
594+
595+
let write_result = lock.try_write();
596+
match write_result {
597+
Err(TryLockError::WouldBlock) => (),
598+
Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"),
599+
Err(_) => assert!(false, "unexpected error"),
600+
}
601+
602+
drop(read_guard);
603+
}
580604
}

0 commit comments

Comments
 (0)