summaryrefslogtreecommitdiff
path: root/src/windows7.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows7.rs')
-rwxr-xr-xsrc/windows7.rs119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/windows7.rs b/src/windows7.rs
new file mode 100755
index 0000000..2007d05
--- /dev/null
+++ b/src/windows7.rs
@@ -0,0 +1,119 @@
+use core::cell::UnsafeCell;
+
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct SrwLock {
+ ptr: *mut core::ffi::c_void,
+}
+
+const SRWLOCK_INIT: SrwLock = SrwLock {
+ ptr: core::ptr::null_mut(),
+};
+
+type Boolean = u8;
+
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn AcquireSRWLockShared(srwlock: *mut SrwLock);
+ pub fn AcquireSRWLockExclusive(srwlock: *mut SrwLock);
+ pub fn TryAcquireSRWLockShared(srwlock: *mut SrwLock) -> Boolean;
+ pub fn TryAcquireSRWLockExclusive(srwlock: *mut SrwLock) -> Boolean;
+ pub fn ReleaseSRWLockShared(srwlock: *mut SrwLock);
+ pub fn ReleaseSRWLockExclusive(srwlock: *mut SrwLock);
+}
+
+pub struct Mutex(UnsafeCell<SrwLock>);
+
+unsafe impl Send for Mutex {}
+unsafe impl Sync for Mutex {}
+
+impl Mutex {
+ #[inline]
+ pub const fn new() -> Self {
+ Self(UnsafeCell::new(SRWLOCK_INIT))
+ }
+
+ /// Locks the mutex
+ ///
+ /// # Safety
+ ///
+ /// UB occurs if the mutex is already locked by the current thread and the
+ /// `unsafe_lock` feature is enabled.
+ #[inline]
+ pub unsafe fn lock(&self) {
+ unsafe {
+ AcquireSRWLockExclusive(self.0.get());
+ }
+ }
+
+ /// If the mutex is unlocked, it is locked, and this function returns
+ /// `true'. Otherwise, `false` is returned.
+ #[inline]
+ pub unsafe fn try_lock(&self) -> bool {
+ unsafe { TryAcquireSRWLockExclusive(self.0.get()) != 0 }
+ }
+
+ /// Unlocks the mutex
+ ///
+ /// # Safety
+ ///
+ /// UB occurs if the mutex is already unlocked or if it has been locked on
+ /// a different thread.
+ #[inline]
+ pub unsafe fn unlock(&self) {
+ unsafe {
+ ReleaseSRWLockExclusive(self.0.get());
+ }
+ }
+
+ pub unsafe fn is_locked(&self) -> bool {
+ if self.try_lock() {
+ unsafe {
+ self.unlock();
+ }
+ false
+ } else {
+ true
+ }
+ }
+}
+
+pub struct RwLock {
+ inner: UnsafeCell<c::SRWLOCK>,
+}
+
+unsafe impl Send for RwLock {}
+unsafe impl Sync for RwLock {}
+
+impl RwLock {
+ #[inline]
+ pub const fn new() -> RwLock {
+ RwLock {
+ inner: UnsafeCell::new(c::SRWLOCK_INIT),
+ }
+ }
+ #[inline]
+ pub fn read(&self) {
+ unsafe { c::AcquireSRWLockShared(self.inner.get()) }
+ }
+ #[inline]
+ pub fn try_read(&self) -> bool {
+ unsafe { c::TryAcquireSRWLockShared(self.inner.get()) != 0 }
+ }
+ #[inline]
+ pub fn write(&self) {
+ unsafe { c::AcquireSRWLockExclusive(self.inner.get()) }
+ }
+ #[inline]
+ pub fn try_write(&self) -> bool {
+ unsafe { c::TryAcquireSRWLockExclusive(self.inner.get()) != 0 }
+ }
+ #[inline]
+ pub unsafe fn read_unlock(&self) {
+ c::ReleaseSRWLockShared(self.inner.get())
+ }
+ #[inline]
+ pub unsafe fn write_unlock(&self) {
+ c::ReleaseSRWLockExclusive(self.inner.get())
+ }
+}