rustix_futex_sync/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5// Re-export this so that our users can use the same version we do.
6#[cfg(feature = "lock_api")]
7pub use lock_api;
8
9// If we don't have the real `lock_api` crate, use our polyfills.
10#[cfg(not(feature = "lock_api"))]
11pub mod lock_api;
12
13// Export convenient `Mutex` and `RwLock` types.
14#[cfg(feature = "lock_api")]
15pub type Mutex<T> = lock_api::Mutex<RawMutex, T>;
16#[cfg(feature = "lock_api")]
17pub type RwLock<T> = lock_api::RwLock<RawRwLock, T>;
18#[cfg(feature = "lock_api")]
19pub type MutexGuard<'a, T> = lock_api::MutexGuard<'a, RawMutex, T>;
20#[cfg(feature = "lock_api")]
21pub type MappedMutexGuard<'a, T> = lock_api::MappedMutexGuard<'a, RawMutex, T>;
22#[cfg(feature = "lock_api")]
23pub type RwLockReadGuard<'a, T> = lock_api::RwLockReadGuard<'a, RawRwLock, T>;
24#[cfg(feature = "lock_api")]
25pub type RwLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, RawRwLock, T>;
26#[cfg(feature = "lock_api")]
27pub type MappedRwLockReadGuard<'a, T> = lock_api::MappedRwLockReadGuard<'a, RawRwLock, T>;
28#[cfg(feature = "lock_api")]
29pub type MappedRwLockWriteGuard<'a, T> = lock_api::MappedRwLockWriteGuard<'a, RawRwLock, T>;
30#[cfg(feature = "lock_api")]
31#[cfg(feature = "atomic_usize")]
32#[cfg_attr(docsrs, doc(cfg(feature = "atomic_usize")))]
33pub type ReentrantMutex<G, T> = lock_api::ReentrantMutex<RawMutex, G, T>;
34#[cfg(feature = "lock_api")]
35#[cfg(feature = "atomic_usize")]
36#[cfg_attr(docsrs, doc(cfg(feature = "atomic_usize")))]
37pub type ReentrantMutexGuard<'a, G, T> = lock_api::ReentrantMutexGuard<'a, RawMutex, G, T>;
38
39// Export the once types.
40pub use once::{Once, OnceState};
41pub use once_lock::OnceLock;
42
43// Export the condvar types.
44#[cfg(feature = "lock_api")]
45pub use condvar::{Condvar, WaitTimeoutResult};
46
47// Export the raw condvar types.
48pub use futex_condvar::Condvar as RawCondvar;
49
50// std's implementation code.
51#[cfg(feature = "lock_api")]
52mod condvar;
53mod futex_condvar;
54mod futex_mutex;
55mod futex_once;
56mod futex_rwlock;
57mod once;
58mod once_lock;
59mod wait_wake;
60
61/// An implementation of [`lock_api::RawMutex`].
62///
63/// All of this `RawMutex`'s methods are in its implementation of
64/// [`lock_api::RawMutex`]. To import that trait without conflicting
65/// with this `RawMutex` type, use:
66///
67/// ```
68/// use rustix_futex_sync::lock_api::RawMutex as _;
69/// ```
70#[repr(transparent)]
71pub struct RawMutex(futex_mutex::Mutex);
72
73/// An implementation of [`lock_api::RawRwLock`].
74///
75/// All of this `RawRwLock`'s methods are in its implementation of
76/// [`lock_api::RawRwLock`]. To import that trait without conflicting
77/// with this `RawRwLock` type, use:
78///
79/// ```
80/// use rustix_futex_sync::lock_api::RawRwLock as _;
81/// ```
82#[repr(C)]
83pub struct RawRwLock(futex_rwlock::RwLock);
84
85// Implement the raw lock traits for our wrappers.
86
87unsafe impl lock_api::RawMutex for RawMutex {
88    type GuardMarker = lock_api::GuardNoSend;
89
90    const INIT: Self = Self(futex_mutex::Mutex::new());
91
92    #[inline]
93    fn lock(&self) {
94        self.0.lock()
95    }
96
97    #[inline]
98    fn try_lock(&self) -> bool {
99        self.0.try_lock()
100    }
101
102    #[inline]
103    unsafe fn unlock(&self) {
104        self.0.unlock()
105    }
106}
107
108unsafe impl lock_api::RawRwLock for RawRwLock {
109    type GuardMarker = lock_api::GuardNoSend;
110
111    const INIT: Self = Self(futex_rwlock::RwLock::new());
112
113    #[inline]
114    fn lock_shared(&self) {
115        self.0.read()
116    }
117
118    #[inline]
119    fn try_lock_shared(&self) -> bool {
120        self.0.try_read()
121    }
122
123    #[inline]
124    unsafe fn unlock_shared(&self) {
125        self.0.read_unlock()
126    }
127
128    #[inline]
129    fn lock_exclusive(&self) {
130        self.0.write()
131    }
132
133    #[inline]
134    fn try_lock_exclusive(&self) -> bool {
135        self.0.try_write()
136    }
137
138    #[inline]
139    unsafe fn unlock_exclusive(&self) {
140        self.0.write_unlock()
141    }
142}