mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-20 12:38:43 +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::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self, IoSlice, IoSliceMut, Result, SeekFrom},
|
io::{self, IoSlice, IoSliceMut, SeekFrom},
|
||||||
ops,
|
ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,20 +18,54 @@ impl FileLock {
|
||||||
/// Take an exclusive lock on a [`File`].
|
/// Take an exclusive lock on a [`File`].
|
||||||
///
|
///
|
||||||
/// Note that this operation is blocking, and should not be called in async contexts.
|
/// 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()?;
|
file.lock_exclusive()?;
|
||||||
|
|
||||||
Ok(Self(file))
|
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`].
|
/// Take a shared lock on a [`File`].
|
||||||
///
|
///
|
||||||
/// Note that this operation is blocking, and should not be called in async contexts.
|
/// 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()?;
|
file.lock_shared()?;
|
||||||
|
|
||||||
Ok(Self(file))
|
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 {
|
impl Drop for FileLock {
|
||||||
|
@ -54,37 +88,37 @@ impl ops::DerefMut for FileLock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write 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)
|
self.0.write(buf)
|
||||||
}
|
}
|
||||||
fn flush(&mut self) -> Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
self.0.flush()
|
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)
|
self.0.write_vectored(bufs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Read for FileLock {
|
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)
|
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)
|
self.0.read_vectored(bufs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl io::Seek for FileLock {
|
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)
|
self.0.seek(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rewind(&mut self) -> Result<()> {
|
fn rewind(&mut self) -> io::Result<()> {
|
||||||
self.0.rewind()
|
self.0.rewind()
|
||||||
}
|
}
|
||||||
fn stream_position(&mut self) -> Result<u64> {
|
fn stream_position(&mut self) -> io::Result<u64> {
|
||||||
self.0.stream_position()
|
self.0.stream_position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue