Skip to main content

asyncband/mutex/
mod.rs

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