diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-05-27 20:57:53 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-27 20:57:53 +0200 | 
| commit | 88b12f364922aeada0ba3ebc06462a6adb1ffc56 (patch) | |
| tree | 6f57147b1f8ce7189f6a5184bcc7d73ebf57ebce /library/std/src | |
| parent | c583fa6d8425dbb38fe5d1dbd007f9ca8e4aa128 (diff) | |
| parent | fd260d530b880c44874340eaf2e31666a138a874 (diff) | |
| download | rust-88b12f364922aeada0ba3ebc06462a6adb1ffc56.tar.gz rust-88b12f364922aeada0ba3ebc06462a6adb1ffc56.zip | |
Rollup merge of #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 https://github.com/rust-lang/rust/issues/130994 This PR also cleanups the Windows implementation of `try_lock()` and `try_lock_shared()` as [discussed here](https://github.com/rust-lang/rust/pull/140718#discussion_r2076678485)
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/fs.rs | 16 | ||||
| -rw-r--r-- | library/std/src/fs/tests.rs | 22 | ||||
| -rw-r--r-- | library/std/src/sys/fs/windows.rs | 10 | 
3 files changed, 40 insertions, 8 deletions
| diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8047c0c03ad..8ed5800e9d0 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -391,6 +391,16 @@ impl fmt::Display for TryLockError { } } +#[unstable(feature = "file_lock", issue = "130994")] +impl From<TryLockError> for io::Error { + fn from(err: TryLockError) -> io::Error { + match err { + TryLockError::Error(err) => err, + TryLockError::WouldBlock => io::ErrorKind::WouldBlock.into(), + } + } +} + impl File { /// Attempts to open a file in read-only mode. /// @@ -820,11 +830,14 @@ impl File { /// /// fn main() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; + /// // Explicit handling of the WouldBlock error /// match f.try_lock() { /// Ok(_) => (), /// Err(TryLockError::WouldBlock) => (), // Lock not acquired /// Err(TryLockError::Error(err)) => return Err(err), /// } + /// // Alternately, propagate the error as an io::Error + /// f.try_lock()?; /// Ok(()) /// } /// ``` @@ -881,11 +894,14 @@ impl File { /// /// fn main() -> std::io::Result<()> { /// let f = File::open("foo.txt")?; + /// // Explicit handling of the WouldBlock error /// match f.try_lock_shared() { /// Ok(_) => (), /// Err(TryLockError::WouldBlock) => (), // Lock not acquired /// Err(TryLockError::Error(err)) => return Err(err), /// } + /// // Alternately, propagate the error as an io::Error + /// f.try_lock_shared()?; /// /// Ok(()) /// } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index c81a5ff4d96..8da6d75b73e 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -367,6 +367,28 @@ fn file_lock_blocking_async() { } #[test] +#[cfg(windows)] +fn file_try_lock_async() { + const FILE_FLAG_OVERLAPPED: u32 = 0x40000000; + + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_try_lock_async.txt"); + let f1 = check!(File::create(filename)); + let f2 = + check!(OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).write(true).open(filename)); + + // Check that shared locks block exclusive locks + check!(f1.lock_shared()); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + check!(f1.unlock()); + + // Check that exclusive locks block all locks + check!(f1.lock()); + assert_matches!(f2.try_lock(), Err(TryLockError::WouldBlock)); + assert_matches!(f2.try_lock_shared(), Err(TryLockError::WouldBlock)); +} + +#[test] fn file_test_io_seek_shakedown() { // 01234567890123 let initial_msg = "qwer-asdf-zxcv"; diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 9039fd00f5d..d01a572ac73 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -415,10 +415,7 @@ impl File { match result { Ok(_) => Ok(()), - Err(err) - if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) - || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => - { + Err(err) if err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => { Err(TryLockError::WouldBlock) } Err(err) => Err(TryLockError::Error(err)), @@ -440,10 +437,7 @@ impl File { match result { Ok(_) => Ok(()), - Err(err) - if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) - || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => - { + Err(err) if err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) => { Err(TryLockError::WouldBlock) } Err(err) => Err(TryLockError::Error(err)), | 
