about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-27 20:57:53 +0200
committerGitHub <noreply@github.com>2025-05-27 20:57:53 +0200
commit88b12f364922aeada0ba3ebc06462a6adb1ffc56 (patch)
tree6f57147b1f8ce7189f6a5184bcc7d73ebf57ebce /library/std/src
parentc583fa6d8425dbb38fe5d1dbd007f9ca8e4aa128 (diff)
parentfd260d530b880c44874340eaf2e31666a138a874 (diff)
downloadrust-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.rs16
-rw-r--r--library/std/src/fs/tests.rs22
-rw-r--r--library/std/src/sys/fs/windows.rs10
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)),