blob: 2007d059697ce42325d9b416cb63b246e4d3e4cf (
plain)
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())
}
}
|