#![allow(unsafe_code)] //! Backend trait for raw mutex implementations. //! //! Surelock is generic over any locking backend that implements //! [`RawMutex`]. The trait uses a GAT-based guard -- `lock()` returns //! a guard whose `Drop` releases the lock. No separate `unlock()` //! method. //! //! # Built-in Backends //! //! - [`StdMutex`](std_mutex::StdMutex): wraps `std::sync::Mutex<()>` //! (behind the `std` feature, which is the default). //! //! # `lock_api` Interop //! //! Enable the `lock-api` feature for a blanket impl that bridges any //! `lock_api::RawMutex` implementation (`parking_lot`, `spin`, etc.) //! to surelock's trait. No newtype wrappers needed. #[cfg(feature = "lock-api")] pub mod lock_api_adapter; #[cfg(feature = "std")] pub mod std_mutex; /// A raw mutual exclusion primitive. /// /// Implementations provide the low-level lock operations that /// [`Mutex`](crate::mutex::Mutex) delegates to. Unlocking happens /// by dropping the associated [`Guard`](RawMutex::Guard) type -- /// there is no separate `unlock()` method. /// /// # Safety /// /// Implementations must guarantee that: /// - `lock()` blocks until the lock is acquired exclusively. /// - A successful `lock()` or `try_lock()` returns a guard that /// releases the lock on drop. /// - While the guard is alive, no other thread can acquire the lock. /// - The implementation is thread-safe. #[diagnostic::on_unimplemented( message = "`{Self}` is not a mutex backend", note = "implement `RawMutex` for custom backends, or enable the `lock-api` feature for `parking_lot` / `spin` compatibility" )] pub unsafe trait RawMutex { /// RAII guard returned by [`lock`](RawMutex::lock) and /// [`try_lock`](RawMutex::try_lock). Dropping the guard /// releases the lock. type Guard<'a> where Self: 'a; /// Create a new unlocked instance. fn new() -> Self; /// Block until the lock is acquired, returning a guard that /// releases the lock on drop. fn lock(&self) -> Self::Guard<'_>; /// Try to acquire the lock without blocking. /// /// Returns `Some(guard)` if acquired, `None` if the lock is /// already held. fn try_lock(&self) -> Option>; }