diff options
Diffstat (limited to 'vendor/fd-lock/src/sys')
-rw-r--r-- | vendor/fd-lock/src/sys/mod.rs | 17 | ||||
-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 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unsupported/mod.rs | 9 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unsupported/read_guard.rs | 31 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unsupported/rw_lock.rs | 44 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unsupported/utils.rs | 9 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/unsupported/write_guard.rs | 38 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/windows/mod.rs | 8 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/windows/read_guard.rs | 31 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/windows/rw_lock.rs | 72 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/windows/utils.rs | 33 | ||||
-rw-r--r-- | vendor/fd-lock/src/sys/windows/write_guard.rs | 38 |
15 files changed, 478 insertions, 0 deletions
diff --git a/vendor/fd-lock/src/sys/mod.rs b/vendor/fd-lock/src/sys/mod.rs new file mode 100644 index 000000000..3c6391e98 --- /dev/null +++ b/vendor/fd-lock/src/sys/mod.rs @@ -0,0 +1,17 @@ +use cfg_if::cfg_if; + +cfg_if! { + if #[cfg(unix)] { + mod unix; + pub use unix::*; + pub(crate) use std::os::unix::prelude::AsRawFd as AsRaw; + } else if #[cfg(windows)] { + mod windows; + pub use windows::*; + #[doc(no_inline)] + pub(crate) use std::os::windows::prelude::AsRawHandle as AsRaw; + } else { + mod unsupported; + pub use unsupported; + } +} 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(); + } +} diff --git a/vendor/fd-lock/src/sys/unsupported/mod.rs b/vendor/fd-lock/src/sys/unsupported/mod.rs new file mode 100644 index 000000000..9d7bd2cbd --- /dev/null +++ b/vendor/fd-lock/src/sys/unsupported/mod.rs @@ -0,0 +1,9 @@ +mod read_guard; +mod rw_lock; +mod write_guard; + +pub(crate) mod utils; + +pub use read_guard::RwLockReadGuard; +pub use rw_lock::RwLock; +pub use write_guard::RwLockWriteGuard; diff --git a/vendor/fd-lock/src/sys/unsupported/read_guard.rs b/vendor/fd-lock/src/sys/unsupported/read_guard.rs new file mode 100644 index 000000000..7d6b4c783 --- /dev/null +++ b/vendor/fd-lock/src/sys/unsupported/read_guard.rs @@ -0,0 +1,31 @@ +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 { + panic!("target unsupported") + } +} + +impl<T: AsRawFd> ops::Deref for RwLockReadGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + panic!("target unsupported") + } +} + +impl<T: AsRawFd> Drop for RwLockReadGuard<'_, T> { + #[inline] + fn drop(&mut self) { + panic!("target unsupported") + } +} diff --git a/vendor/fd-lock/src/sys/unsupported/rw_lock.rs b/vendor/fd-lock/src/sys/unsupported/rw_lock.rs new file mode 100644 index 000000000..fb11da84b --- /dev/null +++ b/vendor/fd-lock/src/sys/unsupported/rw_lock.rs @@ -0,0 +1,44 @@ +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 { + panic!("target unsupported") + } + + #[inline] + pub fn write(&mut self) -> io::Result<RwLockWriteGuard<'_, T>> { + panic!("target unsupported") + } + + #[inline] + pub fn try_write(&mut self) -> Result<RwLockWriteGuard<'_, T>, Error> { + panic!("target unsupported") + } + + #[inline] + pub fn read(&self) -> io::Result<RwLockReadGuard<'_, T>> { + panic!("target unsupported") + } + + #[inline] + pub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, Error> { + panic!("target unsupported") + } + + #[inline] + pub fn into_inner(self) -> T + where + T: Sized, + { + panic!("target unsupported") + } +} diff --git a/vendor/fd-lock/src/sys/unsupported/utils.rs b/vendor/fd-lock/src/sys/unsupported/utils.rs new file mode 100644 index 000000000..191dd0c5c --- /dev/null +++ b/vendor/fd-lock/src/sys/unsupported/utils.rs @@ -0,0 +1,9 @@ +use std::io; +use std::os::raw::c_int; + +pub(crate) fn syscall(int: c_int) -> io::Result<()> { + match int { + 0 => Ok(()), + _ => Err(io::Error::last_os_error()), + } +} diff --git a/vendor/fd-lock/src/sys/unsupported/write_guard.rs b/vendor/fd-lock/src/sys/unsupported/write_guard.rs new file mode 100644 index 000000000..19727c307 --- /dev/null +++ b/vendor/fd-lock/src/sys/unsupported/write_guard.rs @@ -0,0 +1,38 @@ +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 { + panic!("target unsupported") + } +} + +impl<T: AsRawFd> ops::Deref for RwLockWriteGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + panic!("target unsupported") + } +} + +impl<T: AsRawFd> ops::DerefMut for RwLockWriteGuard<'_, T> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + panic!("target unsupported") + } +} + +impl<T: AsRawFd> Drop for RwLockWriteGuard<'_, T> { + #[inline] + fn drop(&mut self) { + panic!("target unsupported") + } +} diff --git a/vendor/fd-lock/src/sys/windows/mod.rs b/vendor/fd-lock/src/sys/windows/mod.rs new file mode 100644 index 000000000..dafbd31ad --- /dev/null +++ b/vendor/fd-lock/src/sys/windows/mod.rs @@ -0,0 +1,8 @@ +mod read_guard; +mod rw_lock; +mod utils; +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/windows/read_guard.rs b/vendor/fd-lock/src/sys/windows/read_guard.rs new file mode 100644 index 000000000..28f09bb95 --- /dev/null +++ b/vendor/fd-lock/src/sys/windows/read_guard.rs @@ -0,0 +1,31 @@ +use windows_sys::Win32::Foundation::HANDLE; +use windows_sys::Win32::Storage::FileSystem::UnlockFile; + +use std::ops; +use std::os::windows::prelude::*; + +use super::utils::syscall; +use super::RwLock; + +#[derive(Debug)] +pub struct RwLockReadGuard<'lock, T: AsRawHandle> { + pub(crate) lock: &'lock RwLock<T>, +} + +impl<T: AsRawHandle> ops::Deref for RwLockReadGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.lock.inner + } +} + +impl<T: AsRawHandle> Drop for RwLockReadGuard<'_, T> { + #[inline] + fn drop(&mut self) { + let handle = self.lock.inner.as_raw_handle() as HANDLE; + syscall(unsafe { UnlockFile(handle, 0, 0, 1, 0) }) + .expect("Could not unlock the file descriptor"); + } +} diff --git a/vendor/fd-lock/src/sys/windows/rw_lock.rs b/vendor/fd-lock/src/sys/windows/rw_lock.rs new file mode 100644 index 000000000..778b79100 --- /dev/null +++ b/vendor/fd-lock/src/sys/windows/rw_lock.rs @@ -0,0 +1,72 @@ +use std::io::{self, Error, ErrorKind}; +use std::os::windows::io::AsRawHandle; + +use windows_sys::Win32::Foundation::HANDLE; +use windows_sys::Win32::Storage::FileSystem::{ + LockFileEx, LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, +}; + +use super::utils::{syscall, Overlapped}; +use super::{RwLockReadGuard, RwLockWriteGuard}; + +#[derive(Debug)] +pub struct RwLock<T: AsRawHandle> { + pub(crate) inner: T, +} + +impl<T: AsRawHandle> RwLock<T> { + #[inline] + pub fn new(inner: T) -> Self { + RwLock { inner } + } + + #[inline] + pub fn read(&self) -> io::Result<RwLockReadGuard<'_, T>> { + // See: https://stackoverflow.com/a/9186532, https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex + let handle = self.inner.as_raw_handle() as HANDLE; + let overlapped = Overlapped::zero(); + let flags = 0; + syscall(unsafe { LockFileEx(handle, flags, 0, 1, 0, overlapped.raw()) })?; + Ok(RwLockReadGuard { lock: self }) + } + + #[inline] + pub fn try_read(&self) -> io::Result<RwLockReadGuard<'_, T>> { + let handle = self.inner.as_raw_handle() as HANDLE; + let overlapped = Overlapped::zero(); + let flags = LOCKFILE_FAIL_IMMEDIATELY; + + syscall(unsafe { LockFileEx(handle, flags, 0, 1, 0, overlapped.raw()) }) + .map_err(|_| Error::from(ErrorKind::WouldBlock))?; + Ok(RwLockReadGuard { lock: self }) + } + + #[inline] + pub fn write(&mut self) -> io::Result<RwLockWriteGuard<'_, T>> { + // See: https://stackoverflow.com/a/9186532, https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex + let handle = self.inner.as_raw_handle() as HANDLE; + let overlapped = Overlapped::zero(); + let flags = LOCKFILE_EXCLUSIVE_LOCK; + syscall(unsafe { LockFileEx(handle, flags, 0, 1, 0, overlapped.raw()) })?; + Ok(RwLockWriteGuard { lock: self }) + } + + #[inline] + pub fn try_write(&mut self) -> io::Result<RwLockWriteGuard<'_, T>> { + let handle = self.inner.as_raw_handle() as HANDLE; + let overlapped = Overlapped::zero(); + let flags = LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK; + + syscall(unsafe { LockFileEx(handle, flags, 0, 1, 0, overlapped.raw()) }) + .map_err(|_| Error::from(ErrorKind::WouldBlock))?; + Ok(RwLockWriteGuard { lock: self }) + } + + #[inline] + pub fn into_inner(self) -> T + where + T: Sized, + { + self.inner + } +} diff --git a/vendor/fd-lock/src/sys/windows/utils.rs b/vendor/fd-lock/src/sys/windows/utils.rs new file mode 100644 index 000000000..43656a083 --- /dev/null +++ b/vendor/fd-lock/src/sys/windows/utils.rs @@ -0,0 +1,33 @@ +use std::io; +use std::mem; + +use windows_sys::Win32::Foundation::BOOL; +use windows_sys::Win32::System::IO::OVERLAPPED; + +/// A wrapper around `OVERLAPPED` to provide "rustic" accessors and +/// initializers. +pub(crate) struct Overlapped(OVERLAPPED); + +impl Overlapped { + /// Creates a new zeroed out instance of an overlapped I/O tracking state. + /// + /// This is suitable for passing to methods which will then later get + /// notified via an I/O Completion Port. + pub(crate) fn zero() -> Overlapped { + Overlapped(unsafe { mem::zeroed() }) + } + + /// Gain access to the raw underlying data + pub(crate) fn raw(&self) -> *mut OVERLAPPED { + &self.0 as *const _ as *mut _ + } +} + +/// Convert a system call which returns a `BOOL` to an `io::Result`. +pub(crate) fn syscall(status: BOOL) -> std::io::Result<()> { + if status == 0 { + Err(io::Error::last_os_error()) + } else { + Ok(()) + } +} diff --git a/vendor/fd-lock/src/sys/windows/write_guard.rs b/vendor/fd-lock/src/sys/windows/write_guard.rs new file mode 100644 index 000000000..5494bd99e --- /dev/null +++ b/vendor/fd-lock/src/sys/windows/write_guard.rs @@ -0,0 +1,38 @@ +use windows_sys::Win32::Foundation::HANDLE; +use windows_sys::Win32::Storage::FileSystem::UnlockFile; + +use std::ops; +use std::os::windows::prelude::*; + +use super::utils::syscall; +use super::RwLock; + +#[derive(Debug)] +pub struct RwLockWriteGuard<'lock, T: AsRawHandle> { + pub(crate) lock: &'lock mut RwLock<T>, +} + +impl<T: AsRawHandle> ops::Deref for RwLockWriteGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.lock.inner + } +} + +impl<T: AsRawHandle> ops::DerefMut for RwLockWriteGuard<'_, T> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.lock.inner + } +} + +impl<T: AsRawHandle> Drop for RwLockWriteGuard<'_, T> { + #[inline] + fn drop(&mut self) { + let handle = self.lock.inner.as_raw_handle() as HANDLE; + syscall(unsafe { UnlockFile(handle, 0, 0, 1, 0) }) + .expect("Could not unlock the file descriptor"); + } +} |