use zx::sys;
extern "C" {
fn sync_mutex_lock(lock: *const sys::zx_futex_t);
fn sync_mutex_trylock(lock: *const sys::zx_futex_t) -> sys::zx_status_t;
fn sync_mutex_unlock(lock: *const sys::zx_futex_t);
}
const SYNC_MUTEX_INIT: i32 = 0;
#[repr(transparent)]
pub struct RawSyncMutex(sys::zx_futex_t);
impl RawSyncMutex {
#[inline]
fn as_futex_ptr(&self) -> *const sys::zx_futex_t {
std::ptr::addr_of!(self.0)
}
}
unsafe impl lock_api::RawMutex for RawSyncMutex {
const INIT: RawSyncMutex = RawSyncMutex(sys::zx_futex_t::new(SYNC_MUTEX_INIT));
type GuardMarker = lock_api::GuardSend;
#[inline]
fn lock(&self) {
unsafe {
sync_mutex_lock(self.as_futex_ptr());
}
}
#[inline]
fn try_lock(&self) -> bool {
unsafe { sync_mutex_trylock(self.as_futex_ptr()) == sys::ZX_OK }
}
#[inline]
unsafe fn unlock(&self) {
sync_mutex_unlock(self.as_futex_ptr())
}
}
pub type Mutex<T> = lock_api::Mutex<RawSyncMutex, T>;
pub type MutexGuard<'a, T> = lock_api::MutexGuard<'a, RawSyncMutex, T>;
pub type MappedMutexGuard<'a, T> = lock_api::MappedMutexGuard<'a, RawSyncMutex, T>;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_lock_and_unlock() {
let value = Mutex::<u32>::new(5);
let mut guard = value.lock();
assert_eq!(*guard, 5);
*guard = 6;
assert_eq!(*guard, 6);
std::mem::drop(guard);
}
#[test]
fn test_try_lock() {
let value = Mutex::<u32>::new(5);
let _guard = value.lock();
assert!(value.try_lock().is_none());
}
}