summaryrefslogtreecommitdiffstats
path: root/vendor/fd-lock/src/sys/windows
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/fd-lock/src/sys/windows
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/fd-lock/src/sys/windows')
-rw-r--r--vendor/fd-lock/src/sys/windows/mod.rs8
-rw-r--r--vendor/fd-lock/src/sys/windows/read_guard.rs31
-rw-r--r--vendor/fd-lock/src/sys/windows/rw_lock.rs72
-rw-r--r--vendor/fd-lock/src/sys/windows/utils.rs33
-rw-r--r--vendor/fd-lock/src/sys/windows/write_guard.rs38
5 files changed, 182 insertions, 0 deletions
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");
+ }
+}