surelock 0.1.0

Deadlock-free locks for Rust with compile time guarantees, incremental locks, and atomic lock sets.
Documentation
#![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<Self::Guard<'_>>;
}