mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-24 22:30:03 +00:00
feat(fs-lock): new_try_exclusive and new_try_shared (#1496)
In certain situations it's useful to attempt to lock the file.
This commit is contained in:
parent
9d8dc94d8d
commit
645579430a
1 changed files with 45 additions and 11 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, IoSlice, IoSliceMut, Result, SeekFrom},
|
||||
io::{self, IoSlice, IoSliceMut, SeekFrom},
|
||||
ops,
|
||||
};
|
||||
|
||||
|
@ -18,20 +18,54 @@ impl FileLock {
|
|||
/// Take an exclusive lock on a [`File`].
|
||||
///
|
||||
/// Note that this operation is blocking, and should not be called in async contexts.
|
||||
pub fn new_exclusive(file: File) -> Result<Self> {
|
||||
pub fn new_exclusive(file: File) -> io::Result<Self> {
|
||||
file.lock_exclusive()?;
|
||||
|
||||
Ok(Self(file))
|
||||
}
|
||||
|
||||
/// Try to take an exclusive lock on a [`File`].
|
||||
///
|
||||
/// On success returns [`Self`]. On error the original [`File`] and optionally
|
||||
/// an [`io::Error`] if the the failure was caused by anything other than
|
||||
/// the lock being taken already.
|
||||
///
|
||||
/// Note that this operation is blocking, and should not be called in async contexts.
|
||||
pub fn new_try_exclusive(file: File) -> Result<Self, (File, Option<io::Error>)> {
|
||||
match file.try_lock_exclusive() {
|
||||
Ok(()) => Ok(Self(file)),
|
||||
Err(e) if e.raw_os_error() == fs4::lock_contended_error().raw_os_error() => {
|
||||
Err((file, None))
|
||||
}
|
||||
Err(e) => Err((file, Some(e))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Take a shared lock on a [`File`].
|
||||
///
|
||||
/// Note that this operation is blocking, and should not be called in async contexts.
|
||||
pub fn new_shared(file: File) -> Result<Self> {
|
||||
pub fn new_shared(file: File) -> io::Result<Self> {
|
||||
file.lock_shared()?;
|
||||
|
||||
Ok(Self(file))
|
||||
}
|
||||
|
||||
/// Try to take a shared lock on a [`File`].
|
||||
///
|
||||
/// On success returns [`Self`]. On error the original [`File`] and optionally
|
||||
/// an [`io::Error`] if the the failure was caused by anything other than
|
||||
/// the lock being taken already.
|
||||
///
|
||||
/// Note that this operation is blocking, and should not be called in async contexts.
|
||||
pub fn new_try_shared(file: File) -> Result<Self, (File, Option<io::Error>)> {
|
||||
match file.try_lock_shared() {
|
||||
Ok(()) => Ok(Self(file)),
|
||||
Err(e) if e.raw_os_error() == fs4::lock_contended_error().raw_os_error() => {
|
||||
Err((file, None))
|
||||
}
|
||||
Err(e) => Err((file, Some(e))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FileLock {
|
||||
|
@ -54,37 +88,37 @@ impl ops::DerefMut for FileLock {
|
|||
}
|
||||
|
||||
impl io::Write for FileLock {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.flush()
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for FileLock {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
|
||||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Seek for FileLock {
|
||||
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
|
||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||
self.0.seek(pos)
|
||||
}
|
||||
|
||||
fn rewind(&mut self) -> Result<()> {
|
||||
fn rewind(&mut self) -> io::Result<()> {
|
||||
self.0.rewind()
|
||||
}
|
||||
fn stream_position(&mut self) -> Result<u64> {
|
||||
fn stream_position(&mut self) -> io::Result<u64> {
|
||||
self.0.stream_position()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue