From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/fd-lock/src/sys/windows/mod.rs | 8 +++ vendor/fd-lock/src/sys/windows/read_guard.rs | 31 ++++++++++++ vendor/fd-lock/src/sys/windows/rw_lock.rs | 72 +++++++++++++++++++++++++++ vendor/fd-lock/src/sys/windows/utils.rs | 33 ++++++++++++ vendor/fd-lock/src/sys/windows/write_guard.rs | 38 ++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 vendor/fd-lock/src/sys/windows/mod.rs create mode 100644 vendor/fd-lock/src/sys/windows/read_guard.rs create mode 100644 vendor/fd-lock/src/sys/windows/rw_lock.rs create mode 100644 vendor/fd-lock/src/sys/windows/utils.rs create mode 100644 vendor/fd-lock/src/sys/windows/write_guard.rs (limited to 'vendor/fd-lock/src/sys/windows') 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, +} + +impl ops::Deref for RwLockReadGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.lock.inner + } +} + +impl 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 { + pub(crate) inner: T, +} + +impl RwLock { + #[inline] + pub fn new(inner: T) -> Self { + RwLock { inner } + } + + #[inline] + pub fn read(&self) -> io::Result> { + // 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> { + 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> { + // 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> { + 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, +} + +impl ops::Deref for RwLockWriteGuard<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.lock.inner + } +} + +impl ops::DerefMut for RwLockWriteGuard<'_, T> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.lock.inner + } +} + +impl 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"); + } +} -- cgit v1.2.3