Skip to main content

Crate lock_api

Crate lock_api 

Source
Expand description

This library provides type-safe and fully-featured Mutex, RwLock, and Condvar types which wrap simple raw synchronization primitives. This has several benefits: not only does it eliminate a large portion of the work in implementing custom lock types, it also allows users to write code which is generic with regard to different lock implementations.

Basic usage of this crate is very straightforward:

  1. Create a raw lock type. This should only contain the lock state, not any data protected by the lock.
  2. Implement the RawMutex trait for your custom lock type.
  3. Export your mutex as a type alias for lock_api::Mutex, and your mutex guard as a type alias for lock_api::MutexGuard. See the example below for details.

This process is similar for RwLocks, except that two guards need to be exported instead of one (or three guards if your type supports upgradable read locks; see extension traits below for details). A Condvar additionally requires a RawCondvar implementation tied to the raw mutex type with which it can be used.

§Example

use lock_api::{RawMutex, Mutex, GuardSend};
use std::sync::atomic::{AtomicBool, Ordering};

// 1. Define our raw lock type
pub struct RawSpinlock(AtomicBool);

// 2. Implement RawMutex for this type
unsafe impl RawMutex for RawSpinlock {
    const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));

    // A spinlock guard can be sent to another thread and unlocked there
    type Guard = GuardSend;

    fn lock(&self) -> Self::Guard {
        // Note: This isn't the best way of implementing a spinlock, but it
        // suffices for the sake of this example.
        loop {
            if let Some(guard) = self.try_lock() {
                return guard;
            }
        }
    }

    fn try_lock(&self) -> Option<Self::Guard> {
        self.0
            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
            .ok().map(|_| GuardSend::new())
    }

    unsafe fn unlock(&self, _guard: Self::Guard) {
        self.0.store(false, Ordering::Release);
    }

    fn is_locked(&self) -> bool {
        self.0.load(Ordering::Relaxed)
    }
}

// 3. Export the wrappers. These are the types that users will actually use.
pub type Spinlock<T> = lock_api::Mutex<RawSpinlock, T>;
pub type SpinlockGuard<'a, T> = lock_api::MutexGuard<'a, RawSpinlock, T>;

§Extension traits

In addition to basic locking & unlocking functionality, you have the option of exposing additional functionality in your lock types by implementing additional traits for it. Examples of extension features include:

The Mutex and RwLock wrappers will automatically expose this additional functionality if the raw lock type implements these extension traits.

§Cargo features

This crate provides the following Cargo features:

  • atomic_usize: Enables reentrant mutex types, which require pointer-sized atomic operations. This feature is enabled by default.
  • arc_lock: Enables locking from an Arc and types such as ArcMutexGuard. This requires the alloc crate.
  • owning_ref: Allows lock guards to be used with the owning_ref crate.
  • serde: Enables serialization and deserialization of lock types.

Structs§

ArcMutexGuardarc_lock
An RAII mutex guard returned by the Arc locking operations on Mutex.
ArcReentrantMutexGuardarc_lock and atomic_usize
An RAII mutex guard returned by the Arc locking operations on ReentrantMutex.
ArcRwLockReadGuardarc_lock
An RAII read guard returned by the Arc locking operations on RwLock.
ArcRwLockUpgradableReadGuardarc_lock
An RAII upgradable read guard returned by the Arc locking operations on RwLock. Unlike RwLockUpgradableReadGuard, this guard owns the Arc used to unlock the reader-writer lock instead of borrowing it, so its lifetime is not tied to a lock reference.
ArcRwLockWriteGuardarc_lock
An RAII write guard returned by the Arc locking operations on RwLock. Unlike RwLockWriteGuard, this guard owns the Arc used to unlock the reader-writer lock instead of borrowing it, so its lifetime is not tied to a lock reference.
Condvar
A condition variable.
GuardNoSend
A stateless guard which is not Send.
GuardSend
A stateless guard which is Send.
MappedMutexGuard
An RAII mutex guard returned by MutexGuard::map, which can point to a subfield of the protected data.
MappedReentrantMutexGuardatomic_usize
An RAII mutex guard returned by ReentrantMutexGuard::map, which can point to a subfield of the protected data.
MappedRwLockReadGuard
An RAII read lock guard returned by RwLockReadGuard::map, which can point to a subfield of the protected data.
MappedRwLockWriteGuard
An RAII write lock guard returned by RwLockWriteGuard::map, which can point to a subfield of the protected data.
Mutex
A mutual exclusion primitive useful for protecting shared data.
MutexGuard
An RAII guard which unlocks the mutex when dropped.
RawReentrantMutexatomic_usize
A raw mutex type that wraps another raw mutex to provide reentrancy.
ReentrantMutexatomic_usize
A reentrant mutual exclusion lock.
ReentrantMutexGuardatomic_usize
An RAII guard which releases one level of recursive locking when dropped.
RwLock
A reader-writer lock.
RwLockReadGuard
An RAII guard which releases shared read access when dropped.
RwLockUpgradableReadGuard
An RAII guard which releases upgradable read access when dropped.
RwLockWriteGuard
An RAII guard which releases exclusive write access when dropped.
WaitTimeoutResult
A type indicating whether a timed wait on a condition variable timed out.

Traits§

GetThreadIdatomic_usize
Helper trait which returns a non-zero thread ID.
RawCondvar
Basic operations for a condition variable associated with a particular RawMutex implementation.
RawCondvarTimed
Additional methods for condition variables which support timeouts.
RawMutex
Basic operations for a mutex.
RawMutexFair
Additional methods for mutexes which support fair unlocking.
RawMutexTimed
Additional methods for mutexes which support locking with timeouts.
RawRwLock
Basic operations for a reader-writer lock.
RawRwLockDowngrade
Additional methods for RwLocks which support atomically downgrading an exclusive lock to a shared lock.
RawRwLockFair
Additional methods for RwLocks which support fair unlocking.
RawRwLockTimed
Additional methods for RwLocks which support locking with timeouts.
RawRwLockUpgrade
Additional methods for RwLocks which support atomically upgrading a shared lock to an exclusive lock.
RawRwLockUpgradeDowngrade
Additional methods for RwLocks which support upgradable locks and lock downgrading.
RawRwLockUpgradeFair
Additional methods for RwLocks which support upgradable locks and fair unlocking.
RawRwLockUpgradeTimed
Additional methods for RwLocks which support upgradable locks and locking with timeouts.