|
21 | 21 | mod tests; |
22 | 22 |
|
23 | 23 | use crate::ffi::OsString; |
24 | | -use crate::fmt; |
25 | 24 | use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; |
26 | 25 | use crate::path::{Path, PathBuf}; |
27 | 26 | use crate::sealed::Sealed; |
28 | 27 | use crate::sync::Arc; |
29 | 28 | use crate::sys::fs as fs_imp; |
30 | 29 | use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; |
31 | 30 | use crate::time::SystemTime; |
| 31 | +use crate::{error, fmt}; |
32 | 32 |
|
33 | 33 | /// An object providing access to an open file on the filesystem. |
34 | 34 | /// |
@@ -116,6 +116,22 @@ pub struct File { |
116 | 116 | inner: fs_imp::File, |
117 | 117 | } |
118 | 118 |
|
| 119 | +/// An enumeration of possible errors which can occur while trying to acquire a lock |
| 120 | +/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`]. |
| 121 | +/// |
| 122 | +/// [`try_lock`]: File::try_lock |
| 123 | +/// [`try_lock_shared`]: File::try_lock_shared |
| 124 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 125 | +pub enum TryLockError { |
| 126 | + /// The lock could not be acquired due to an I/O error on the file. The standard library will |
| 127 | + /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`] |
| 128 | + /// |
| 129 | + /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock |
| 130 | + Error(io::Error), |
| 131 | + /// The lock could not be acquired at this time because it is held by another handle/process. |
| 132 | + WouldBlock, |
| 133 | +} |
| 134 | + |
119 | 135 | /// Metadata information about a file. |
120 | 136 | /// |
121 | 137 | /// This structure is returned from the [`metadata`] or |
@@ -352,6 +368,30 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result |
352 | 368 | inner(path.as_ref(), contents.as_ref()) |
353 | 369 | } |
354 | 370 |
|
| 371 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 372 | +impl error::Error for TryLockError {} |
| 373 | + |
| 374 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 375 | +impl fmt::Debug for TryLockError { |
| 376 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 377 | + match self { |
| 378 | + TryLockError::Error(err) => err.fmt(f), |
| 379 | + TryLockError::WouldBlock => "WouldBlock".fmt(f), |
| 380 | + } |
| 381 | + } |
| 382 | +} |
| 383 | + |
| 384 | +#[unstable(feature = "file_lock", issue = "130994")] |
| 385 | +impl fmt::Display for TryLockError { |
| 386 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 387 | + match self { |
| 388 | + TryLockError::Error(_) => "lock acquisition failed due to I/O error", |
| 389 | + TryLockError::WouldBlock => "lock acquisition failed because the operation would block", |
| 390 | + } |
| 391 | + .fmt(f) |
| 392 | + } |
| 393 | +} |
| 394 | + |
355 | 395 | impl File { |
356 | 396 | /// Attempts to open a file in read-only mode. |
357 | 397 | /// |
@@ -734,8 +774,8 @@ impl File { |
734 | 774 |
|
735 | 775 | /// Try to acquire an exclusive lock on the file. |
736 | 776 | /// |
737 | | - /// Returns `Ok(false)` if a different lock is already held on this file (via another |
738 | | - /// handle/descriptor). |
| 777 | + /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file |
| 778 | + /// (via another handle/descriptor). |
739 | 779 | /// |
740 | 780 | /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. |
741 | 781 | /// |
@@ -777,23 +817,27 @@ impl File { |
777 | 817 | /// |
778 | 818 | /// ```no_run |
779 | 819 | /// #![feature(file_lock)] |
780 | | - /// use std::fs::File; |
| 820 | + /// use std::fs::{File, TryLockError}; |
781 | 821 | /// |
782 | 822 | /// fn main() -> std::io::Result<()> { |
783 | 823 | /// let f = File::create("foo.txt")?; |
784 | | - /// f.try_lock()?; |
| 824 | + /// match f.try_lock() { |
| 825 | + /// Ok(_) => (), |
| 826 | + /// Err(TryLockError::WouldBlock) => (), // Lock not acquired |
| 827 | + /// Err(TryLockError::Error(err)) => return Err(err), |
| 828 | + /// } |
785 | 829 | /// Ok(()) |
786 | 830 | /// } |
787 | 831 | /// ``` |
788 | 832 | #[unstable(feature = "file_lock", issue = "130994")] |
789 | | - pub fn try_lock(&self) -> io::Result<bool> { |
| 833 | + pub fn try_lock(&self) -> Result<(), TryLockError> { |
790 | 834 | self.inner.try_lock() |
791 | 835 | } |
792 | 836 |
|
793 | 837 | /// Try to acquire a shared (non-exclusive) lock on the file. |
794 | 838 | /// |
795 | | - /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another |
796 | | - /// handle/descriptor). |
| 839 | + /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file |
| 840 | + /// (via another handle/descriptor). |
797 | 841 | /// |
798 | 842 | /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may |
799 | 843 | /// hold an exclusive lock at the same time. |
@@ -834,16 +878,21 @@ impl File { |
834 | 878 | /// |
835 | 879 | /// ```no_run |
836 | 880 | /// #![feature(file_lock)] |
837 | | - /// use std::fs::File; |
| 881 | + /// use std::fs::{File, TryLockError}; |
838 | 882 | /// |
839 | 883 | /// fn main() -> std::io::Result<()> { |
840 | 884 | /// let f = File::open("foo.txt")?; |
841 | | - /// f.try_lock_shared()?; |
| 885 | + /// match f.try_lock_shared() { |
| 886 | + /// Ok(_) => (), |
| 887 | + /// Err(TryLockError::WouldBlock) => (), // Lock not acquired |
| 888 | + /// Err(TryLockError::Error(err)) => return Err(err), |
| 889 | + /// } |
| 890 | + /// |
842 | 891 | /// Ok(()) |
843 | 892 | /// } |
844 | 893 | /// ``` |
845 | 894 | #[unstable(feature = "file_lock", issue = "130994")] |
846 | | - pub fn try_lock_shared(&self) -> io::Result<bool> { |
| 895 | + pub fn try_lock_shared(&self) -> Result<(), TryLockError> { |
847 | 896 | self.inner.try_lock_shared() |
848 | 897 | } |
849 | 898 |
|
|
0 commit comments