guarded.rs

Overview

This file provides a set of traits and implementations to facilitate safe, synchronized access to inner data protected by a mutex wrapper. It defines abstractions for guarded (immutable) and guarded mutable access patterns, especially in multi-threaded contexts where data must be locked and unlocked properly. The main focus is on using Arc<Mutex<T>> to allow shared ownership and mutually exclusive access to the inner data.

The traits allow executing closures on the locked inner data, abstracting away manual locking and unlocking. Additionally, support for "try" locking (non-blocking lock attempts) is provided. The design also includes a customizable mechanism (AllowGuardedMut) to allow inner types to control how mutable access is provided.

Traits and Their Purpose

AllowGuardedMut

pub trait AllowGuardedMut {
    fn inner_guarded_mut<F, T>(&mut self, action: F) -> T
    where
        F: FnOnce(&mut Self) -> T,
    {
        action(self)
    }
}

Guarded<Inner>

pub trait Guarded<Inner> {
    fn guarded<F, T>(&self, action: F) -> T
    where
        F: FnOnce(&Inner) -> T;
}

GuardedMut<Inner>

pub trait GuardedMut<Inner> {
    fn guarded_mut<F, T>(&self, action: F) -> T
    where
        F: FnOnce(&mut Inner) -> T;
}

TryGuardedMut<Inner>

pub trait TryGuardedMut<Inner> {
    fn try_guarded_mut<F, T>(&self, action: F) -> Option<T>
    where
        F: FnOnce(&mut Inner) -> T;
}

Implementations

All implemented for Arc<Mutex<Inner>> type, leveraging the parking_lot::Mutex for efficient locking.

Guarded<Inner> for Arc<Mutex<Inner>>

GuardedMut<Inner> for Arc<Mutex<Inner>> where Inner: AllowGuardedMut

TryGuardedMut<Inner> for Arc<Mutex<Inner>> where Inner: AllowGuardedMut

Important Implementation Details

Interaction with Other Parts of the System

Usage Examples

Immutable access example

use std::sync::Arc;
use parking_lot::Mutex;

let data = Arc::new(Mutex::new(42));
let result = data.guarded(|val| *val + 1);
assert_eq!(result, 43);

Mutable access example with AllowGuardedMut default

use std::sync::Arc;
use parking_lot::Mutex;

let data = Arc::new(Mutex::new(5));
data.guarded_mut(|val| *val += 10);
assert_eq!(data.guarded(|val| *val), 15);

Try mutable access example

use std::sync::Arc;
use parking_lot::Mutex;

let data = Arc::new(Mutex::new(100));
if let Some(new_val) = data.try_guarded_mut(|val| {
    *val += 1;
    *val
}) {
    println!("New value: {}", new_val);
} else {
    println!("Could not acquire lock");
}

Mermaid Class Diagram

classDiagram
class AllowGuardedMut {
+inner_guarded_mut()
}
class Guarded~Inner~ {
+guarded()
}
class GuardedMut~Inner~ {
+guarded_mut()
}
class TryGuardedMut~Inner~ {
+try_guarded_mut()
}
class ArcMutex~Inner~ {
<<implements>> Guarded~Inner~
<<implements>> GuardedMut~Inner~
<<implements>> TryGuardedMut~Inner~
}
AllowGuardedMut <|.. ArcMutex~Inner~
Guarded~Inner~ <|.. ArcMutex~Inner~
GuardedMut~Inner~ <|.. ArcMutex~Inner~
TryGuardedMut~Inner~ <|.. ArcMutex~Inner~

This diagram shows the key traits defined in the file and their implementation by Arc<Mutex<Inner>>, illustrating the trait-based abstraction of guarded access mechanisms.