diff options
Diffstat (limited to 'vendor/fd-lock/src/sys/unix')
-rw-r--r-- | vendor/fd-lock/src/sys/unix/mod.rs | 7 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unix/read_guard.rs | 32 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unix/rw_lock.rs | 70 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unix/write_guard.rs | 39 |
4 files changed, 148 insertions, 0 deletions
diff --git a/vendor/fd-lock/src/sys/unix/mod.rs b/vendor/fd-lock/src/sys/unix/mod.rs new file mode 100644 index 000000000..023e69187 --- /dev/null +++ b/vendor/fd-lock/src/sys/unix/mod.rs @@ -0,0 +1,7 @@ +mod read_guard; +mod rw_lock; +mod write_guard; + +pub use read_guard::RwLockReadGuard; +pub use rw_lock::RwLock; +pub use write_guard::RwLockWriteGuard; diff --git a/vendor/fd-lock/src/sys/unix/read_guard.rs b/vendor/fd-lock/src/sys/unix/read_guard.rs new file mode 100644 index 000000000..6d6718789 --- /dev/null +++ b/vendor/fd-lock/src/sys/unix/read_guard.rs @@ -0,0 +1,32 @@ +use rustix::fs::{flock, FlockOperation}; +use std::ops; +use std::os::unix::io::AsRawFd; + +use super::RwLock; + +#[derive(Debug)] +pub struct RwLockReadGuard<'lock, T: AsRawFd> { + lock: &'lock RwLock<T>, +} + +impl<'lock, T: AsRawFd> RwLockReadGuard<'lock, T> { + pub(crate) fn new(lock: &'lock RwLock<T>) -> Self { + Self { lock } + } +} + +impl<T: AsRawFd> ops::Deref for RwLockReadGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.lock.inner + } +} + +impl<T: AsRawFd> Drop for RwLockReadGuard<'_, T> { + #[inline] + fn drop(&mut self) { + let _ = flock(&self.lock.as_fd(), FlockOperation::Unlock).ok(); + } +} diff --git a/vendor/fd-lock/src/sys/unix/rw_lock.rs b/vendor/fd-lock/src/sys/unix/rw_lock.rs new file mode 100644 index 000000000..c33ce5c78 --- /dev/null +++ b/vendor/fd-lock/src/sys/unix/rw_lock.rs @@ -0,0 +1,70 @@ +use rustix::fd::BorrowedFd; +use rustix::fs::{flock, FlockOperation}; +use std::io::{self, Error, ErrorKind}; +use std::os::unix::io::AsRawFd; + +use super::{RwLockReadGuard, RwLockWriteGuard}; + +#[derive(Debug)] +pub struct RwLock<T: AsRawFd> { + pub(crate) inner: T, +} + +impl<T: AsRawFd> RwLock<T> { + #[inline] + pub fn new(inner: T) -> Self { + RwLock { inner } + } + + #[inline] + pub fn write(&mut self) -> io::Result<RwLockWriteGuard<'_, T>> { + flock(&self.as_fd(), FlockOperation::LockExclusive)?; + Ok(RwLockWriteGuard::new(self)) + } + + #[inline] + pub fn try_write(&mut self) -> Result<RwLockWriteGuard<'_, T>, Error> { + flock(&self.as_fd(), FlockOperation::NonBlockingLockExclusive).map_err(|err| match err + .kind() + { + ErrorKind::AlreadyExists => ErrorKind::WouldBlock.into(), + _ => Error::from(err), + })?; + Ok(RwLockWriteGuard::new(self)) + } + + #[inline] + pub fn read(&self) -> io::Result<RwLockReadGuard<'_, T>> { + flock(&self.as_fd(), FlockOperation::LockShared)?; + Ok(RwLockReadGuard::new(self)) + } + + #[inline] + pub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, Error> { + flock(&self.as_fd(), FlockOperation::NonBlockingLockShared).map_err(|err| { + match err.kind() { + ErrorKind::AlreadyExists => ErrorKind::WouldBlock.into(), + _ => Error::from(err), + } + })?; + Ok(RwLockReadGuard::new(self)) + } + + #[inline] + pub fn into_inner(self) -> T + where + T: Sized, + { + self.inner + } + + #[inline] + pub(crate) fn as_fd(&self) -> BorrowedFd<'_> { + // Safety: We assume that `self.inner`'s file descriptor is valid for + // at least the lifetime of `self`. + // + // Once I/O safety is stablized in std, we can switch the public API to + // use `AsFd` instead of `AsRawFd` and eliminate this `unsafe` block. + unsafe { BorrowedFd::borrow_raw(self.inner.as_raw_fd()) } + } +} diff --git a/vendor/fd-lock/src/sys/unix/write_guard.rs b/vendor/fd-lock/src/sys/unix/write_guard.rs new file mode 100644 index 000000000..a12bdf97a --- /dev/null +++ b/vendor/fd-lock/src/sys/unix/write_guard.rs @@ -0,0 +1,39 @@ +use rustix::fs::{flock, FlockOperation}; +use std::ops; +use std::os::unix::io::AsRawFd; + +use super::RwLock; + +#[derive(Debug)] +pub struct RwLockWriteGuard<'lock, T: AsRawFd> { + lock: &'lock mut RwLock<T>, +} + +impl<'lock, T: AsRawFd> RwLockWriteGuard<'lock, T> { + pub(crate) fn new(lock: &'lock mut RwLock<T>) -> Self { + Self { lock } + } +} + +impl<T: AsRawFd> ops::Deref for RwLockWriteGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.lock.inner + } +} + +impl<T: AsRawFd> ops::DerefMut for RwLockWriteGuard<'_, T> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.lock.inner + } +} + +impl<T: AsRawFd> Drop for RwLockWriteGuard<'_, T> { + #[inline] + fn drop(&mut self) { + let _ = flock(&self.lock.as_fd(), FlockOperation::Unlock).ok(); + } +} |