Skip to main content

openraft_rt/
mutex.rs

1//! Async mutex trait.
2
3use std::future::Future;
4use std::ops::Deref;
5use std::ops::DerefMut;
6use std::sync::Arc;
7
8use crate::OptionalSend;
9use crate::OptionalSync;
10
11/// Represents an implementation of an asynchronous Mutex.
12pub trait Mutex<T>: OptionalSend + OptionalSync + 'static
13where T: OptionalSend + 'static
14{
15    /// Handle to an acquired lock, should release it when dropped.
16    type Guard<'a>: DerefMut<Target = T> + OptionalSend
17    where Self: 'a;
18
19    /// Creates a new lock.
20    #[track_caller]
21    fn new(value: T) -> Self;
22
23    /// Locks this Mutex.
24    #[track_caller]
25    fn lock(&self) -> impl Future<Output = Self::Guard<'_>> + OptionalSend;
26
27    /// Lock this mutex, returning a guard that owns the mutex via Arc.
28    ///
29    /// The guard can be moved, returned from functions, or stored in structs.
30    /// This is provided as a default implementation for convenience.
31    #[must_use]
32    fn lock_owned(self: Arc<Self>) -> impl Future<Output = OwnedGuard<Self, T>> + OptionalSend
33    where Self: Sized {
34        async move {
35            let guard = self.lock().await;
36
37            // SAFETY: OwnedGuard holds the Arc, ensuring mutex outlives the guard.
38            // We transmute the guard to 'static lifetime because its lifetime is
39            // now tied to the Arc in OwnedGuard, not the original borrow.
40            let guard_static = unsafe { std::mem::transmute::<Self::Guard<'_>, Self::Guard<'static>>(guard) };
41
42            OwnedGuard {
43                guard: guard_static,
44                _mutex: self,
45            }
46        }
47    }
48}
49
50/// An owned guard that keeps the mutex alive via Arc.
51///
52/// This guard owns the lock through an `Arc<Mutex>`, allowing it to outlive
53/// the original reference and be moved, returned from functions, or stored in structs.
54pub struct OwnedGuard<M, T>
55where
56    M: Mutex<T>,
57    T: OptionalSend + 'static,
58{
59    guard: M::Guard<'static>,
60    _mutex: Arc<M>,
61}
62
63impl<M, T> Deref for OwnedGuard<M, T>
64where
65    M: Mutex<T>,
66    T: OptionalSend + 'static,
67{
68    type Target = T;
69    fn deref(&self) -> &Self::Target {
70        &self.guard
71    }
72}
73
74impl<M, T> DerefMut for OwnedGuard<M, T>
75where
76    M: Mutex<T>,
77    T: OptionalSend + 'static,
78{
79    fn deref_mut(&mut self) -> &mut Self::Target {
80        &mut self.guard
81    }
82}