mea/mutex/
mod.rs

1// Copyright 2024 tison <wander4096@gmail.com>
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! An async mutex for protecting shared data.
16//!
17//! Unlike a standard mutex, this implementation is designed to work with async/await,
18//! ensuring tasks yield properly when the lock is contended. This makes it suitable
19//! for protecting shared resources in async code.
20//!
21//! This mutex will block tasks waiting for the lock to become available. The
22//! mutex can be created via [`new`] and the protected data can be accessed
23//! via the async [`lock`] method.
24//!
25//! # Examples
26//!
27//! ```
28//! # #[tokio::main]
29//! # async fn main() {
30//! use std::sync::Arc;
31//!
32//! use mea::mutex::Mutex;
33//!
34//! let mutex = Arc::new(Mutex::new(0));
35//! let mut handles = Vec::new();
36//!
37//! for i in 0..3 {
38//!     let mutex = mutex.clone();
39//!     handles.push(tokio::spawn(async move {
40//!         let mut lock = mutex.lock().await;
41//!         *lock += i;
42//!     }));
43//! }
44//!
45//! for handle in handles {
46//!     handle.await.unwrap();
47//! }
48//!
49//! let final_value = mutex.lock().await;
50//! assert_eq!(*final_value, 3); // 0 + 1 + 2
51//!
52//! #  }
53//! ```
54//!
55//! [`new`]: Mutex::new
56//! [`lock`]: Mutex::lock
57
58use std::cell::UnsafeCell;
59use std::fmt;
60use std::marker::PhantomData;
61use std::mem::ManuallyDrop;
62use std::ops::Deref;
63use std::ops::DerefMut;
64use std::ptr::NonNull;
65use std::sync::Arc;
66
67use crate::internal;
68
69#[cfg(test)]
70mod test;
71
72/// An async mutex for protecting shared data.
73///
74/// See the [module level documentation](self) for more.
75pub struct Mutex<T: ?Sized> {
76    /// Semaphore used to control access to protected data, ensuring mutual exclusion
77    s: internal::Semaphore,
78    /// Container storing the protected data, allowing interior mutability
79    c: UnsafeCell<T>,
80}
81
82unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
83unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
84
85impl<T> From<T> for Mutex<T> {
86    fn from(t: T) -> Self {
87        Self::new(t)
88    }
89}
90
91impl<T: Default> Default for Mutex<T> {
92    fn default() -> Self {
93        Self::new(T::default())
94    }
95}
96
97impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        let mut d = f.debug_struct("Mutex");
100        match self.try_lock() {
101            Some(inner) => d.field("data", &&*inner),
102            None => d.field("data", &format_args!("<locked>")),
103        };
104        d.finish()
105    }
106}
107
108impl<T> Mutex<T> {
109    /// Creates a new mutex in an unlocked state ready for use.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use mea::mutex::Mutex;
115    ///
116    /// let mutex = Mutex::new(5);
117    /// ```
118    pub const fn new(t: T) -> Self {
119        let s = internal::Semaphore::new(1);
120        let c = UnsafeCell::new(t);
121        Self { s, c }
122    }
123
124    /// Consumes the mutex, returning the underlying data.
125    ///
126    /// # Examples
127    ///
128    /// ```
129    /// use mea::mutex::Mutex;
130    ///
131    /// let mutex = Mutex::new(1);
132    /// let n = mutex.into_inner();
133    /// assert_eq!(n, 1);
134    /// ```
135    pub fn into_inner(self) -> T {
136        self.c.into_inner()
137    }
138}
139
140impl<T: ?Sized> Mutex<T> {
141    /// Locks this mutex, causing the current task to yield until the lock has been acquired. When
142    /// the lock has been acquired, function returns a [`MutexGuard`].
143    ///
144    /// This method is async and will yield the current task if the mutex is currently held by
145    /// another task. When the mutex becomes available, the task will be woken up and given the
146    /// lock.
147    ///
148    /// # Cancel safety
149    ///
150    /// This method uses a queue to fairly distribute locks in the order they were requested.
151    /// Cancelling a call to `lock` makes you lose your place in the queue.
152    ///
153    /// # Examples
154    ///
155    /// ```
156    /// # #[tokio::main]
157    /// # async fn main() {
158    /// use mea::mutex::Mutex;
159    ///
160    /// let mutex = Mutex::new(1);
161    ///
162    /// let mut n = mutex.lock().await;
163    /// *n = 2;
164    /// # }
165    /// ```
166    pub async fn lock(&self) -> MutexGuard<'_, T> {
167        self.s.acquire(1).await;
168        MutexGuard { lock: self }
169    }
170
171    /// Attempts to acquire the lock, and returns `None` if the lock is currently held somewhere
172    /// else.
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// use mea::mutex::Mutex;
178    ///
179    /// let mutex = Mutex::new(1);
180    /// let mut guard = mutex.try_lock().expect("mutex is locked");
181    /// *guard += 1;
182    /// assert_eq!(2, *guard);
183    /// ```
184    pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
185        if self.s.try_acquire(1) {
186            let guard = MutexGuard { lock: self };
187            Some(guard)
188        } else {
189            None
190        }
191    }
192
193    /// Locks this mutex, causing the current task to yield until the lock has been acquired. When
194    /// the lock has been acquired, this returns an [`OwnedMutexGuard`].
195    ///
196    /// This method is async and will yield the current task if the mutex is currently held by
197    /// another task. When the mutex becomes available, the task will be woken up and given the
198    /// lock.
199    ///
200    /// This method is identical to [`Mutex::lock`], except that the returned guard references the
201    /// `Mutex` with an [`Arc`] rather than by borrowing it. Therefore, the `Mutex` must be
202    /// wrapped in an `Arc` to call this method, and the guard will live for the `'static` lifetime,
203    /// as it keeps the `Mutex` alive by holding an `Arc`.
204    ///
205    /// # Cancel safety
206    ///
207    /// This method uses a queue to fairly distribute locks in the order they were requested.
208    /// Cancelling a call to `lock_owned` makes you lose your place in the queue.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// # #[tokio::main]
214    /// # async fn main() {
215    /// use std::sync::Arc;
216    ///
217    /// use mea::mutex::Mutex;
218    ///
219    /// let mutex = Arc::new(Mutex::new(1));
220    ///
221    /// let mut n = mutex.clone().lock_owned().await;
222    /// *n = 2;
223    /// # }
224    /// ```
225    pub async fn lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
226        self.s.acquire(1).await;
227        OwnedMutexGuard { lock: self }
228    }
229
230    /// Attempts to acquire the lock, and returns `None` if the lock is currently held somewhere
231    /// else.
232    ///
233    /// This method is identical to [`Mutex::try_lock`], except that the returned guard references
234    /// the `Mutex` with an [`Arc`] rather than by borrowing it. Therefore, the `Mutex` must be
235    /// wrapped in an `Arc` to call this method, and the guard will live for the `'static` lifetime,
236    /// as it keeps the `Mutex` alive by holding an `Arc`.
237    ///
238    /// # Examples
239    ///
240    /// ```
241    /// use std::sync::Arc;
242    ///
243    /// use mea::mutex::Mutex;
244    ///
245    /// let mutex = Arc::new(Mutex::new(1));
246    /// let mut guard = mutex.clone().try_lock_owned().expect("mutex is locked");
247    /// *guard += 1;
248    /// assert_eq!(2, *guard);
249    /// ```
250    pub fn try_lock_owned(self: Arc<Self>) -> Option<OwnedMutexGuard<T>> {
251        if self.s.try_acquire(1) {
252            let guard = OwnedMutexGuard { lock: self };
253            Some(guard)
254        } else {
255            None
256        }
257    }
258
259    /// Returns a mutable reference to the underlying data.
260    ///
261    /// Since this call borrows the `Mutex` mutably, no actual locking needs to take place: the
262    /// mutable borrow statically guarantees no locks exist.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// use mea::mutex::Mutex;
268    ///
269    /// let mut mutex = Mutex::new(1);
270    /// let n = mutex.get_mut();
271    /// *n = 2;
272    /// ```
273    pub fn get_mut(&mut self) -> &mut T {
274        self.c.get_mut()
275    }
276}
277
278/// RAII structure used to release the exclusive lock on a mutex when dropped.
279///
280/// This structure is created by the [`lock`] and [`try_lock`] methods on [`Mutex`].
281///
282/// [`lock`]: Mutex::lock
283/// [`try_lock`]: Mutex::try_lock
284///
285/// See the [module level documentation](self) for more.
286#[must_use = "if unused the Mutex will immediately unlock"]
287pub struct MutexGuard<'a, T: ?Sized> {
288    lock: &'a Mutex<T>,
289}
290
291pub(crate) fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a Mutex<T> {
292    guard.lock
293}
294
295unsafe impl<T: ?Sized + Send + Sync> Sync for MutexGuard<'_, T> {}
296
297impl<T: ?Sized> Drop for MutexGuard<'_, T> {
298    fn drop(&mut self) {
299        self.lock.s.release(1);
300    }
301}
302
303impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
304    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305        fmt::Debug::fmt(&**self, f)
306    }
307}
308
309impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311        fmt::Display::fmt(&**self, f)
312    }
313}
314
315impl<T: ?Sized> Deref for MutexGuard<'_, T> {
316    type Target = T;
317    fn deref(&self) -> &Self::Target {
318        unsafe { &*self.lock.c.get() }
319    }
320}
321
322impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
323    fn deref_mut(&mut self) -> &mut Self::Target {
324        unsafe { &mut *self.lock.c.get() }
325    }
326}
327
328impl<'a, T: ?Sized> MutexGuard<'a, T> {
329    /// Makes a new [`MappedMutexGuard`] for a component of the locked data.
330    ///
331    /// This operation cannot fail as the `MutexGuard` passed in already locked the mutex.
332    ///
333    /// This is an associated function that needs to be used as `MutexGuard::map(...)`. A method
334    /// would interfere with methods of the same name on the contents of the locked data.
335    ///
336    /// # Examples
337    ///
338    /// ```
339    /// # #[tokio::main]
340    /// # async fn main() {
341    /// use mea::mutex::Mutex;
342    /// use mea::mutex::MutexGuard;
343    ///
344    /// #[derive(Debug)]
345    /// struct User {
346    ///     id: u32,
347    ///     profile: UserProfile,
348    /// }
349    ///
350    /// #[derive(Debug)]
351    /// struct UserProfile {
352    ///     email: String,
353    ///     name: String,
354    /// }
355    ///
356    /// let user = User {
357    ///     id: 1,
358    ///     profile: UserProfile {
359    ///         email: "user@example.com".to_owned(),
360    ///         name: "Alice".to_owned(),
361    ///     },
362    /// };
363    ///
364    /// let mutex = Mutex::new(user);
365    /// let guard = mutex.lock().await;
366    ///
367    /// // Map to only access the user's profile, allowing fine-grained locking
368    /// let profile_guard = MutexGuard::map(guard, |user| &mut user.profile);
369    /// assert_eq!(profile_guard.email, "user@example.com");
370    /// # }
371    /// ```
372    pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
373    where
374        F: FnOnce(&mut T) -> &mut U,
375        U: ?Sized,
376    {
377        let d = NonNull::from(f(&mut *orig));
378        let orig = ManuallyDrop::new(orig);
379        MappedMutexGuard {
380            d,
381            s: &orig.lock.s,
382            variance: PhantomData,
383        }
384    }
385
386    /// Attempts to make a new [`MappedMutexGuard`] for a component of the locked data. The
387    /// original guard is returned if the closure returns `None`.
388    ///
389    /// This operation cannot fail as the `MutexGuard` passed in already locked the mutex.
390    ///
391    /// This is an associated function that needs to be used as `MutexGuard::filter_map(...)`.
392    ///
393    /// A method would interfere with methods of the same name on the contents of the locked data.
394    ///
395    /// # Examples
396    ///
397    /// ```
398    /// # #[tokio::main]
399    /// # async fn main() {
400    /// use mea::mutex::Mutex;
401    /// use mea::mutex::MutexGuard;
402    ///
403    /// #[derive(Debug)]
404    /// struct Database {
405    ///     users: std::collections::HashMap<u32, String>,
406    ///     admin_user_id: Option<u32>,
407    /// }
408    ///
409    /// let mut db = Database {
410    ///     users: std::collections::HashMap::new(),
411    ///     admin_user_id: Some(1),
412    /// };
413    /// db.users.insert(1, "admin@example.com".to_owned());
414    ///
415    /// let mutex = Mutex::new(db);
416    /// let guard = mutex.lock().await;
417    ///
418    /// // Try to map to admin user's email if admin exists
419    /// let admin_email_guard = MutexGuard::filter_map(guard, |db| {
420    ///     if let Some(admin_id) = db.admin_user_id {
421    ///         db.users.get_mut(&admin_id)
422    ///     } else {
423    ///         None
424    ///     }
425    /// })
426    /// .expect("admin user should exist");
427    ///
428    /// assert_eq!(&*admin_email_guard, "admin@example.com");
429    /// # }
430    /// ```
431    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
432    where
433        F: FnOnce(&mut T) -> Option<&mut U>,
434        U: ?Sized,
435    {
436        match f(&mut *orig) {
437            Some(d) => {
438                let d = NonNull::from(d);
439                let orig = ManuallyDrop::new(orig);
440                Ok(MappedMutexGuard {
441                    d,
442                    s: &orig.lock.s,
443                    variance: PhantomData,
444                })
445            }
446            None => Err(orig),
447        }
448    }
449}
450
451/// An owned handle to a held `Mutex`.
452///
453/// This guard is only available from a [`Mutex`] that is wrapped in an [`Arc`]. It is identical to
454/// [`MutexGuard`], except that rather than borrowing the `Mutex`, it clones the `Arc`, incrementing
455/// the reference count. This means that unlike `MutexGuard`, it will have the `'static` lifetime.
456///
457/// As long as you have this guard, you have exclusive access to the underlying `T`. The guard
458/// internally keeps a reference-counted pointer to the original `Mutex`, so even if the lock goes
459/// away, the guard remains valid.
460///
461/// The lock is automatically released whenever the guard is dropped, at which point `lock` will
462/// succeed yet again.
463///
464/// See the [module level documentation](self) for more.
465#[must_use = "if unused the Mutex will immediately unlock"]
466pub struct OwnedMutexGuard<T: ?Sized> {
467    lock: Arc<Mutex<T>>,
468}
469
470pub(crate) fn owned_guard_lock<T: ?Sized>(guard: &OwnedMutexGuard<T>) -> Arc<Mutex<T>> {
471    guard.lock.clone()
472}
473
474unsafe impl<T: ?Sized + Send + Sync> Sync for OwnedMutexGuard<T> {}
475
476impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
477    fn drop(&mut self) {
478        self.lock.s.release(1);
479    }
480}
481
482impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
483    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484        fmt::Debug::fmt(&**self, f)
485    }
486}
487
488impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
489    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
490        fmt::Display::fmt(&**self, f)
491    }
492}
493
494impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
495    type Target = T;
496    fn deref(&self) -> &Self::Target {
497        unsafe { &*self.lock.c.get() }
498    }
499}
500
501impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
502    fn deref_mut(&mut self) -> &mut Self::Target {
503        unsafe { &mut *self.lock.c.get() }
504    }
505}
506
507impl<T: ?Sized> OwnedMutexGuard<T> {
508    /// Makes a new [`OwnedMappedMutexGuard`] for a component of the locked data.
509    ///
510    /// This operation cannot fail as the `OwnedMutexGuard` passed in already locked the mutex.
511    ///
512    /// This is an associated function that needs to be used as `OwnedMutexGuard::map(...)`. A
513    /// method would interfere with methods of the same name on the contents of the locked data.
514    ///
515    /// # Examples
516    ///
517    /// ```
518    /// # #[tokio::main]
519    /// # async fn main() {
520    /// use std::sync::Arc;
521    ///
522    /// use mea::mutex::Mutex;
523    /// use mea::mutex::OwnedMutexGuard;
524    ///
525    /// struct Config {
526    ///     name: String,
527    ///     value: u32,
528    /// }
529    ///
530    /// let config = Config {
531    ///     name: "front size".to_owned(),
532    ///     value: 42,
533    /// };
534    ///
535    /// let mutex = Arc::new(Mutex::new(config));
536    /// let guard = mutex.clone().lock_owned().await;
537    ///
538    /// // Map to access only the value field
539    /// let value_guard = OwnedMutexGuard::map(guard, |config| &mut config.value);
540    /// assert_eq!(*value_guard, 42);
541    /// # }
542    /// ```
543    pub fn map<U, F>(mut orig: Self, f: F) -> OwnedMappedMutexGuard<T, U>
544    where
545        F: FnOnce(&mut T) -> &mut U,
546        U: ?Sized,
547    {
548        let d = NonNull::from(f(&mut *orig));
549
550        let guard = ManuallyDrop::new(orig);
551
552        let lock = unsafe { std::ptr::read(&guard.lock) };
553
554        OwnedMappedMutexGuard {
555            lock,
556            d,
557            variance: PhantomData,
558        }
559    }
560
561    /// Attempts to make a new [`OwnedMappedMutexGuard`] for a component of the locked data. The
562    /// original guard is returned if the closure returns `None`.
563    ///
564    /// This operation cannot fail as the `OwnedMutexGuard` passed in already locked the mutex.
565    ///
566    /// This is an associated function that needs to be used as `OwnedMutexGuard::filter_map(...)`.
567    ///
568    /// A method would interfere with methods of the same name on the contents of the locked data.
569    ///
570    /// # Examples
571    ///
572    /// ```
573    /// # #[tokio::main]
574    /// # async fn main() {
575    /// use std::sync::Arc;
576    ///
577    /// use mea::mutex::Mutex;
578    /// use mea::mutex::OwnedMutexGuard;
579    ///
580    /// let data = vec![1, 2, 3, 4, 5];
581    /// let mutex = Arc::new(Mutex::new(data));
582    /// let guard = mutex.clone().lock_owned().await;
583    ///
584    /// // Map to the first element
585    /// let first_guard =
586    ///     OwnedMutexGuard::filter_map(guard, |vec| vec.get_mut(0)).expect("vec should not be empty");
587    ///
588    /// assert_eq!(*first_guard, 1);
589    /// # }
590    /// ```
591    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
592    where
593        F: FnOnce(&mut T) -> Option<&mut U>,
594        U: ?Sized,
595    {
596        match f(&mut *orig) {
597            Some(d) => {
598                let d = NonNull::from(d);
599                let guard = ManuallyDrop::new(orig);
600
601                // SAFETY: We safely extract the Arc from the ManuallyDrop guard
602                let lock = unsafe { std::ptr::read(&guard.lock) };
603
604                Ok(OwnedMappedMutexGuard {
605                    lock,
606                    d,
607                    variance: PhantomData,
608                })
609            }
610            None => Err(orig),
611        }
612    }
613}
614
615/// RAII structure used to release the exclusive lock on a mutex when dropped, for a mapped
616/// component of the locked data.
617///
618/// This structure is created by the [`map`] and [`filter_map`] methods on [`MutexGuard`]. It allows
619/// you to hold a lock on a subfield of the protected data, enabling more fine-grained access
620/// control while maintaining the same locking semantics.
621///
622/// As long as you have this guard, you have exclusive access to the underlying `T`. The guard
623/// internally keeps a reference to the original mutex's semaphore, so the original lock is
624/// maintained until this guard is dropped.
625///
626/// `MappedMutexGuard` implements [`Send`] and [`Sync`]
627/// when the underlying data type supports these traits, allowing it to be used across task
628/// boundaries and shared between threads safely.
629///
630/// See the [module level documentation](self) for more.
631///
632/// [`map`]: MutexGuard::map
633/// [`filter_map`]: MutexGuard::filter_map
634///
635/// # Examples
636///
637/// ```
638/// # #[tokio::main]
639/// # async fn main() {
640/// use mea::mutex::Mutex;
641/// use mea::mutex::MutexGuard;
642///
643/// #[derive(Debug)]
644/// struct User {
645///     id: u32,
646///     profile: UserProfile,
647/// }
648///
649/// #[derive(Debug)]
650/// struct UserProfile {
651///     email: String,
652///     name: String,
653/// }
654///
655/// let user = User {
656///     id: 1,
657///     profile: UserProfile {
658///         email: "user@example.com".to_owned(),
659///         name: "Alice".to_owned(),
660///     },
661/// };
662///
663/// let mutex = Mutex::new(user);
664/// let guard = mutex.lock().await;
665/// let profile_guard = MutexGuard::map(guard, |user| &mut user.profile);
666///
667/// // Now we can only access the user's profile
668/// assert_eq!(profile_guard.email, "user@example.com");
669/// # }
670/// ```
671#[must_use = "if unused the Mutex will immediately unlock"]
672pub struct MappedMutexGuard<'a, T: ?Sized> {
673    /// Non-null pointer to the mapped data
674    d: NonNull<T>,
675    /// Reference to the original mutex's semaphore, used for releasing the lock
676    s: &'a internal::Semaphore,
677    variance: PhantomData<&'a mut T>,
678}
679
680// SAFETY: MappedMutexGuard can be safely sent between threads when T: Send.
681// The guard holds exclusive access to the data protected by the mutex lock,
682// and the NonNull<T> pointer remains valid for the guard's lifetime.
683// This is essential for async tasks that may be moved between threads at .await points.
684unsafe impl<T: ?Sized + Send> Send for MappedMutexGuard<'_, T> {}
685
686// SAFETY: MappedMutexGuard can be safely shared between threads (Sync) when T: Sync.
687// Through &MappedMutexGuard, you can only get &T, so if T itself allows sharing references
688// across threads, then sharing MappedMutexGuard references is also safe.
689unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
690
691impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
692    fn drop(&mut self) {
693        self.s.release(1);
694    }
695}
696
697impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
698    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
699        fmt::Debug::fmt(&**self, f)
700    }
701}
702
703impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
704    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
705        fmt::Display::fmt(&**self, f)
706    }
707}
708
709impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
710    type Target = T;
711    fn deref(&self) -> &Self::Target {
712        // SAFETY: we hold the lock and the NonNull pointer is valid for the guard's lifetime
713        unsafe { self.d.as_ref() }
714    }
715}
716
717impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
718    fn deref_mut(&mut self) -> &mut Self::Target {
719        // SAFETY: we hold the lock and the NonNull pointer is valid for the guard's lifetime
720        unsafe { self.d.as_mut() }
721    }
722}
723
724impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
725    /// Makes a new [`MappedMutexGuard`] for a component of the locked data.
726    ///
727    /// This operation cannot fail as the `MappedMutexGuard` passed in already locked the mutex.
728    ///
729    /// This is an associated function that needs to be used as `MappedMutexGuard::map(...)`. A
730    /// method would interfere with methods of the same name on the contents of the locked data.
731    ///
732    /// # Examples
733    ///
734    /// ```
735    /// # #[tokio::main]
736    /// # async fn main() {
737    /// use mea::mutex::MappedMutexGuard;
738    /// use mea::mutex::Mutex;
739    /// use mea::mutex::MutexGuard;
740    ///
741    /// #[derive(Debug)]
742    /// struct User {
743    ///     id: u32,
744    ///     profile: UserProfile,
745    /// }
746    ///
747    /// #[derive(Debug)]
748    /// struct UserProfile {
749    ///     email: String,
750    ///     name: String,
751    /// }
752    ///
753    /// let user = User {
754    ///     id: 1,
755    ///     profile: UserProfile {
756    ///         email: "user@example.com".to_owned(),
757    ///         name: "Alice".to_owned(),
758    ///     },
759    /// };
760    ///
761    /// let mutex = Mutex::new(user);
762    /// let guard = mutex.lock().await;
763    ///
764    /// // First map to user profile
765    /// let profile_guard = MutexGuard::map(guard, |user| &mut user.profile);
766    /// // Then map to the email field specifically
767    /// let email_guard = MappedMutexGuard::map(profile_guard, |profile| &mut profile.email);
768    ///
769    /// assert_eq!(&*email_guard, "user@example.com");
770    /// # }
771    /// ```
772    pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
773    where
774        F: FnOnce(&mut T) -> &mut U,
775        U: ?Sized,
776    {
777        // Use DerefMut to safely get mutable reference, avoiding explicit unsafe block
778        let d = NonNull::from(f(&mut *orig));
779        let orig = ManuallyDrop::new(orig);
780        MappedMutexGuard {
781            d,
782            s: orig.s,
783            variance: PhantomData,
784        }
785    }
786
787    /// Attempts to make a new [`MappedMutexGuard`] for a component of the locked data. The
788    /// original guard is returned if the closure returns `None`.
789    ///
790    /// This operation cannot fail as the `MappedMutexGuard` passed in already locked the mutex.
791    ///
792    /// This is an associated function that needs to be used as `MappedMutexGuard::filter_map(...)`.
793    /// A method would interfere with methods of the same name on the contents of the locked
794    /// data.
795    ///
796    /// # Examples
797    ///
798    /// ```
799    /// # #[tokio::main]
800    /// # async fn main() {
801    /// use mea::mutex::MappedMutexGuard;
802    /// use mea::mutex::Mutex;
803    /// use mea::mutex::MutexGuard;
804    ///
805    /// #[derive(Debug)]
806    /// struct Data {
807    ///     id: u32,
808    ///     value: Option<String>,
809    /// }
810    ///
811    /// let data = Data {
812    ///     id: 1,
813    ///     value: Some("hello".to_owned()),
814    /// };
815    ///
816    /// let mutex = Mutex::new(data);
817    /// let guard = mutex.lock().await;
818    ///
819    /// // First map to the value field
820    /// let value_guard = MutexGuard::map(guard, |data| &mut data.value);
821    /// // Then try to map to the inner string if it exists
822    /// let string_guard =
823    ///     MappedMutexGuard::filter_map(value_guard, |opt| opt.as_mut()).expect("value should exist");
824    ///
825    /// assert_eq!(&*string_guard, "hello");
826    /// # }
827    /// ```
828    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
829    where
830        F: FnOnce(&mut T) -> Option<&mut U>,
831        U: ?Sized,
832    {
833        // Use DerefMut to safely get mutable reference, avoiding explicit unsafe block
834        match f(&mut *orig) {
835            Some(d) => {
836                let d = NonNull::from(d);
837                let orig = ManuallyDrop::new(orig);
838                Ok(MappedMutexGuard {
839                    d,
840                    s: orig.s,
841                    variance: PhantomData,
842                })
843            }
844            None => Err(orig),
845        }
846    }
847}
848
849/// An owned handle to a held `Mutex` for a mapped component of the locked data.
850///
851/// This guard is only available from a [`Mutex`] that is wrapped in an [`Arc`]. It is similar to
852/// [`MappedMutexGuard`], except that rather than borrowing the `Mutex`, it clones the `Arc`,
853/// incrementing the reference count. This means that unlike `MappedMutexGuard`, it will have
854/// the `'static` lifetime.
855///
856/// This structure is created by the [`map`] and [`filter_map`] methods on [`OwnedMutexGuard`].
857/// It allows you to hold a lock on a subfield of the protected data, enabling more fine-grained
858/// access control while maintaining the same locking semantics.
859///
860/// As long as you have this guard, you have exclusive access to the underlying `U`. The guard
861/// internally keeps a reference-counted pointer to the original `Mutex`, so even if the lock goes
862/// away, the guard remains valid.
863///
864/// The lock is automatically released whenever the guard is dropped, at which point `lock` will
865/// succeed yet again.
866///
867/// See the [module level documentation](self) for more.
868///
869/// [`map`]: OwnedMutexGuard::map
870/// [`filter_map`]: OwnedMutexGuard::filter_map
871///
872/// # Examples
873///
874/// ```
875/// # #[tokio::main]
876/// # async fn main() {
877/// use std::sync::Arc;
878///
879/// use mea::mutex::Mutex;
880/// use mea::mutex::OwnedMutexGuard;
881///
882/// struct Data {
883///     value: u32,
884/// }
885///
886/// let data = Data { value: 42 };
887/// let mutex = Arc::new(Mutex::new(data));
888/// let guard = mutex.clone().lock_owned().await;
889/// let value_guard = OwnedMutexGuard::map(guard, |data| &mut data.value);
890///
891/// assert_eq!(*value_guard, 42);
892/// # }
893/// ```
894#[must_use = "if unused the Mutex will immediately unlock"]
895pub struct OwnedMappedMutexGuard<T: ?Sized, U: ?Sized> {
896    // This Arc acts as an ownership certificate, ensuring the Mutex remains valid
897    // and the lock is not released
898    lock: Arc<Mutex<T>>,
899    // This NonNull pointer precisely points to the subfield U, telling us which
900    // memory location we can operate on, with compile-time guarantee of non-null
901    d: NonNull<U>,
902    variance: PhantomData<U>,
903}
904
905// SAFETY: OwnedMappedMutexGuard can be safely sent between threads when T: Send and U: Send.
906// It holds exclusive access to the data protected by the mutex lock, and the raw pointer
907// remains valid for the guard's lifetime. This is essential for async tasks that may be
908// moved between threads at .await points.
909unsafe impl<T: ?Sized + Send, U: ?Sized + Send> Send for OwnedMappedMutexGuard<T, U> {}
910
911// SAFETY: OwnedMappedMutexGuard can be safely shared between threads (Sync) when T: Send + Sync and
912// U: Send + Sync. Through &OwnedMappedMutexGuard, you can only get &U, so if U itself allows
913// sharing references across threads, then sharing OwnedMappedMutexGuard references is also safe.
914// We require T: Send + Sync for maximum safety and ecosystem compatibility.
915unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Sync for OwnedMappedMutexGuard<T, U> {}
916
917impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
918    fn drop(&mut self) {
919        // Release the lock by calling release on the semaphore
920        self.lock.s.release(1);
921    }
922}
923
924impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
925    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
926        fmt::Debug::fmt(&**self, f)
927    }
928}
929
930impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
931    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
932        fmt::Display::fmt(&**self, f)
933    }
934}
935
936impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
937    type Target = U;
938    fn deref(&self) -> &Self::Target {
939        // SAFETY: we hold the lock and the NonNull pointer is valid for the guard's lifetime
940        // The Arc ensures the underlying data remains valid
941        unsafe { self.d.as_ref() }
942    }
943}
944
945impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
946    fn deref_mut(&mut self) -> &mut Self::Target {
947        // SAFETY: we hold the lock and the NonNull pointer is valid for the guard's lifetime
948        // The Arc ensures the underlying data remains valid
949        unsafe { self.d.as_mut() }
950    }
951}
952
953impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
954    /// Makes a new [`OwnedMappedMutexGuard`] for a component of the locked data.
955    ///
956    /// This operation cannot fail as the `OwnedMappedMutexGuard` passed in already locked the
957    /// mutex.
958    ///
959    /// This is an associated function that needs to be used as `OwnedMappedMutexGuard::map(...)`. A
960    /// method would interfere with methods of the same name on the contents of the locked data.
961    ///
962    /// # Examples
963    ///
964    /// ```
965    /// # #[tokio::main]
966    /// # async fn main() {
967    /// use std::sync::Arc;
968    ///
969    /// use mea::mutex::Mutex;
970    /// use mea::mutex::OwnedMappedMutexGuard;
971    /// use mea::mutex::OwnedMutexGuard;
972    ///
973    /// #[derive(Debug)]
974    /// struct Config {
975    ///     host: String,
976    ///     port: u16,
977    /// }
978    ///
979    /// let config = Config {
980    ///     host: "localhost".to_owned(),
981    ///     port: 8080,
982    /// };
983    ///
984    /// let mutex = Arc::new(Mutex::new(config));
985    /// let guard = mutex.clone().lock_owned().await;
986    ///
987    /// // First map to config
988    /// let config_guard = OwnedMutexGuard::map(guard, |config| &mut config.host);
989    /// // Then map to the host string specifically
990    /// let host_guard = OwnedMappedMutexGuard::map(config_guard, |host| host.as_mut_str());
991    ///
992    /// assert_eq!(&*host_guard, "localhost");
993    /// # }
994    /// ```
995    pub fn map<V, F>(mut orig: Self, f: F) -> OwnedMappedMutexGuard<T, V>
996    where
997        F: FnOnce(&mut U) -> &mut V,
998        V: ?Sized,
999    {
1000        // Use DerefMut to maintain consistency with other map implementations
1001        let d = NonNull::from(f(&mut *orig));
1002        let orig = ManuallyDrop::new(orig);
1003
1004        // SAFETY: We safely extract the Arc from the ManuallyDrop guard
1005        let lock = unsafe { std::ptr::read(&orig.lock) };
1006
1007        OwnedMappedMutexGuard {
1008            lock,
1009            d,
1010            variance: PhantomData,
1011        }
1012    }
1013
1014    /// Attempts to make a new [`OwnedMappedMutexGuard`] for a component of the locked data. The
1015    /// original guard is returned if the closure returns `None`.
1016    ///
1017    /// This operation cannot fail as the `OwnedMappedMutexGuard` passed in already locked the
1018    /// mutex.
1019    ///
1020    /// This is an associated function that needs to be used as
1021    /// `OwnedMappedMutexGuard::filter_map(...)`. A method would interfere with methods of the same
1022    /// name on the contents of the locked data.
1023    ///
1024    /// # Examples
1025    ///
1026    /// ```
1027    /// # #[tokio::main]
1028    /// # async fn main() {
1029    /// use std::sync::Arc;
1030    ///
1031    /// use mea::mutex::Mutex;
1032    /// use mea::mutex::OwnedMappedMutexGuard;
1033    /// use mea::mutex::OwnedMutexGuard;
1034    ///
1035    /// #[derive(Debug)]
1036    /// struct Node {
1037    ///     value: i32,
1038    ///     left: Option<Box<Node>>,
1039    ///     right: Option<Box<Node>>,
1040    /// }
1041    ///
1042    /// let node = Node {
1043    ///     value: 10,
1044    ///     left: Some(Box::new(Node {
1045    ///         value: 5,
1046    ///         left: None,
1047    ///         right: None,
1048    ///     })),
1049    ///     right: None,
1050    /// };
1051    ///
1052    /// let mutex = Arc::new(Mutex::new(node));
1053    /// let guard = mutex.clone().lock_owned().await;
1054    ///
1055    /// // First map to left child
1056    /// let left_guard = OwnedMutexGuard::map(guard, |node| &mut node.left);
1057    /// // Try to access the left child if it exists
1058    /// let child_guard = OwnedMappedMutexGuard::filter_map(left_guard, |left| {
1059    ///     left.as_mut().map(|boxed| boxed.as_mut())
1060    /// })
1061    /// .expect("left child should exist");
1062    ///
1063    /// assert_eq!(child_guard.value, 5);
1064    /// # }
1065    /// ```
1066    pub fn filter_map<V, F>(mut orig: Self, f: F) -> Result<OwnedMappedMutexGuard<T, V>, Self>
1067    where
1068        F: FnOnce(&mut U) -> Option<&mut V>,
1069        V: ?Sized,
1070    {
1071        // Use DerefMut to maintain consistency with other filter_map implementations
1072        match f(&mut *orig) {
1073            Some(d) => {
1074                let d = NonNull::from(d);
1075                let orig = ManuallyDrop::new(orig);
1076
1077                // SAFETY: We safely extract the Arc from the ManuallyDrop guard
1078                let lock = unsafe { std::ptr::read(&orig.lock) };
1079
1080                Ok(OwnedMappedMutexGuard {
1081                    lock,
1082                    d,
1083                    variance: PhantomData,
1084                })
1085            }
1086            None => Err(orig),
1087        }
1088    }
1089}