1use zx::sys;
6
7extern "C" {
8 fn sync_mutex_lock(lock: *const sys::zx_futex_t);
9 fn sync_mutex_trylock(lock: *const sys::zx_futex_t) -> sys::zx_status_t;
10 fn sync_mutex_unlock(lock: *const sys::zx_futex_t);
11}
12
13const SYNC_MUTEX_INIT: i32 = 0;
15
16#[repr(transparent)]
17pub struct RawSyncMutex(sys::zx_futex_t);
18
19impl RawSyncMutex {
20 #[inline]
21 fn as_futex_ptr(&self) -> *const sys::zx_futex_t {
22 std::ptr::addr_of!(self.0)
23 }
24}
25
26unsafe impl lock_api::RawMutex for RawSyncMutex {
30 const INIT: RawSyncMutex = RawSyncMutex(sys::zx_futex_t::new(SYNC_MUTEX_INIT));
31
32 type GuardMarker = lock_api::GuardNoSend;
37
38 #[inline]
39 fn lock(&self) {
40 unsafe {
43 sync_mutex_lock(self.as_futex_ptr());
44 }
45 }
46
47 #[inline]
48 fn try_lock(&self) -> bool {
49 unsafe { sync_mutex_trylock(self.as_futex_ptr()) == sys::ZX_OK }
52 }
53
54 #[inline]
55 unsafe fn unlock(&self) {
56 sync_mutex_unlock(self.as_futex_ptr())
57 }
58}
59
60pub type Mutex<T> = lock_api::Mutex<RawSyncMutex, T>;
61pub type MutexGuard<'a, T> = lock_api::MutexGuard<'a, RawSyncMutex, T>;
62pub type MappedMutexGuard<'a, T> = lock_api::MappedMutexGuard<'a, RawSyncMutex, T>;
63
64#[cfg(test)]
65mod test {
66 use super::*;
67
68 #[test]
69 fn test_lock_and_unlock() {
70 let value = Mutex::<u32>::new(5);
71 let mut guard = value.lock();
72 assert_eq!(*guard, 5);
73 *guard = 6;
74 assert_eq!(*guard, 6);
75 std::mem::drop(guard);
76 }
77
78 #[test]
79 fn test_try_lock() {
80 let value = Mutex::<u32>::new(5);
81 let _guard = value.lock();
82 assert!(value.try_lock().is_none());
83 }
84}