Skip to content

Commit c4389da

Browse files
authored
Rollup merge of rust-lang#141312 - cberner:filelock_from, r=joshtriplett
Add From<TryLockError> for io::Error Adds a `From` impl to make error propagation easier, as discussed in the tracking issue `TryLockError` is unstable under the "file_lock" feature. The related tracking issue is rust-lang#130994 This PR also cleanups the Windows implementation of `try_lock()` and `try_lock_shared()` as [discussed here](rust-lang#140718 (comment))
2 parents d9183fc + f4fcaca commit c4389da

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

std/src/fs.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,16 @@ impl fmt::Display for TryLockError {
391391
}
392392
}
393393

394+
#[unstable(feature = "file_lock", issue = "130994")]
395+
impl From<TryLockError> for io::Error {
396+
fn from(err: TryLockError) -> io::Error {
397+
match err {
398+
TryLockError::Error(err) => err,
399+
TryLockError::WouldBlock => io::ErrorKind::WouldBlock.into(),
400+
}
401+
}
402+
}
403+
394404
impl File {
395405
/// Attempts to open a file in read-only mode.
396406
///
@@ -820,11 +830,14 @@ impl File {
820830
///
821831
/// fn main() -> std::io::Result<()> {
822832
/// let f = File::create("foo.txt")?;
833+
/// // Explicit handling of the WouldBlock error
823834
/// match f.try_lock() {
824835
/// Ok(_) => (),
825836
/// Err(TryLockError::WouldBlock) => (), // Lock not acquired
826837
/// Err(TryLockError::Error(err)) => return Err(err),
827838
/// }
839+
/// // Alternately, propagate the error as an io::Error
840+
/// f.try_lock()?;
828841
/// Ok(())
829842
/// }
830843
/// ```
@@ -881,11 +894,14 @@ impl File {
881894
///
882895
/// fn main() -> std::io::Result<()> {
883896
/// let f = File::open("foo.txt")?;
897+
/// // Explicit handling of the WouldBlock error
884898
/// match f.try_lock_shared() {
885899
/// Ok(_) => (),
886900
/// Err(TryLockError::WouldBlock) => (), // Lock not acquired
887901
/// Err(TryLockError::Error(err)) => return Err(err),
888902
/// }
903+
/// // Alternately, propagate the error as an io::Error
904+
/// f.try_lock_shared()?;
889905
///
890906
/// Ok(())
891907
/// }

std/src/fs/tests.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,28 @@ fn file_lock_blocking_async() {
366366
t.join().unwrap();
367367
}
368368

369+
#[test]
370+
#[cfg(windows)]
371+
fn file_try_lock_async() {
372+
const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
373+
374+
let tmpdir = tmpdir();
375+
let filename = &tmpdir.join("file_try_lock_async.txt");
376+
let f1 = check!(File::create(filename));
377+
let f2 =
378+
check!(OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).write(true).open(filename));
379+
380+
// Check that shared locks block exclusive locks
381+
check!(f1.lock_shared());
382+
assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
383+
check!(f1.unlock());
384+
385+
// Check that exclusive locks block all locks
386+
check!(f1.lock());
387+
assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock));
388+
assert_matches!(f2.try_lock_shared(), Err(TryLockError::WouldBlock));
389+
}
390+
369391
#[test]
370392
fn file_test_io_seek_shakedown() {
371393
// 01234567890123

std/src/sys/fs/windows.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,7 @@ impl File {
415415

416416
match result {
417417
Ok(_) => Ok(()),
418-
Err(err)
419-
if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32)
420-
|| err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) =>
421-
{
418+
Err(err) if err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => {
422419
Err(TryLockError::WouldBlock)
423420
}
424421
Err(err) => Err(TryLockError::Error(err)),
@@ -440,10 +437,7 @@ impl File {
440437

441438
match result {
442439
Ok(_) => Ok(()),
443-
Err(err)
444-
if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32)
445-
|| err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) =>
446-
{
440+
Err(err) if err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => {
447441
Err(TryLockError::WouldBlock)
448442
}
449443
Err(err) => Err(TryLockError::Error(err)),

0 commit comments

Comments
 (0)