7 releases

0.1.6 Nov 15, 2024
0.1.5 Nov 8, 2024

#697 in Concurrency


Used in salish

MIT license

16KB
335 lines

AnyLock Polymorphic Locks

Provides a unified lock interface trait to various underlying lock implementations

Supported Locks

  • std::sync
  • parking_lot
  • tokio::sync

lib.rs:

AnyLock Polymorphic Lock Traits

Provides a unified interface to different underlying lock implementations.

Works as either RwLock or Mutex. For Mutex types, [AnyLock::read()] and [AnyLock::write()] are aliased.

AnyLock provides newtype wrappers around supported locks:

Provider Mutex RwLock
parking_lot crate::ParkingLotMutex crate::ParkingLotRwLock
std::sync crate::StdMutex crate::StdRwLock
tokio crate::TokioMutex crate::TokioRwLock
core::sync crate::CoreRefCell

Async

Async locks using tokio are supported using [AnyLock::async_read()] and [AnyLock::async_write()].

Example

use anylock::AnyLock;
use std::{marker::PhantomData, sync::Arc};

// Using type annotations, you can use AnyLock::new()
let arc_lock_string: Arc<anylock::StdMutex<String>> =
    Arc::new(AnyLock::new("Hello AnyLock".into()));

// Although this is a Mutex, we access it using read() and write()
// to allow AnyLock to be compatible with RwLock APIs.
println!("{}", arc_lock_string.read());

/// Example struct wrapping some inner type T with any kind of lock
#[derive(Default)]
struct MyWrapper<T, Lock>
where
    // Use a trait bound to accept any kind of lock
    Lock: AnyLock<T>,
{
    inner: Arc<Lock>,
    _phantom: PhantomData<T>,
}

impl<T, Lock> MyWrapper<T, Lock>
where
    Lock: AnyLock<T>,
{
    fn new(inner: T) -> Self {
        Self {
            inner: Arc::new(Lock::new(inner)),
            _phantom: PhantomData,
        }
    }
}

// Now we can create MyWrapper with different locks without modifying
// the implementation of MyWrapper itself.

// std::Mutex
let x = MyWrapper::<String, anylock::StdMutex<_>>::new("Hello".into());
println!("{}", x.inner.read());

// parking_lot::RwLock
let x = MyWrapper::<String, anylock::ParkingLotRwLock<String>>::new("Hello".into());

// Acquire write lock and write
*x.inner.write() = "World".into();

// Acquire read lock and read
println!("{:?}", x.inner.read());


Dependencies

~7–13MB
~143K SLoC