diff --git a/tokio/src/sync/mutex.rs b/tokio/src/sync/mutex.rs index 8ae8247704a..6acd28b6255 100644 --- a/tokio/src/sync/mutex.rs +++ b/tokio/src/sync/mutex.rs @@ -573,6 +573,32 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> { marker: marker::PhantomData, }) } + + /// Returns a reference to the original `Mutex`. + /// + /// ``` + /// use tokio::sync::{Mutex, MutexGuard}; + /// + /// async fn unlock_and_relock<'l>(guard: MutexGuard<'l, u32>) -> MutexGuard<'l, u32> { + /// println!("1. contains: {:?}", *guard); + /// let mutex = MutexGuard::mutex(&guard); + /// drop(guard); + /// let guard = mutex.lock().await; + /// println!("2. contains: {:?}", *guard); + /// guard + /// } + /// # + /// # #[tokio::main] + /// # async fn main() { + /// # let mutex = Mutex::new(0u32); + /// # let guard = mutex.lock().await; + /// # unlock_and_relock(guard).await; + /// # } + /// ``` + #[inline] + pub fn mutex(this: &Self) -> &'a Mutex { + this.lock + } } impl Drop for MutexGuard<'_, T> { @@ -608,6 +634,35 @@ impl fmt::Display for MutexGuard<'_, T> { // === impl OwnedMutexGuard === +impl OwnedMutexGuard { + /// Returns a reference to the original `Arc`. + /// + /// ``` + /// use std::sync::Arc; + /// use tokio::sync::{Mutex, OwnedMutexGuard}; + /// + /// async fn unlock_and_relock(guard: OwnedMutexGuard) -> OwnedMutexGuard { + /// println!("1. contains: {:?}", *guard); + /// let mutex: Arc> = OwnedMutexGuard::mutex(&guard).clone(); + /// drop(guard); + /// let guard = mutex.lock_owned().await; + /// println!("2. contains: {:?}", *guard); + /// guard + /// } + /// # + /// # #[tokio::main] + /// # async fn main() { + /// # let mutex = Arc::new(Mutex::new(0u32)); + /// # let guard = mutex.lock_owned().await; + /// # unlock_and_relock(guard).await; + /// # } + /// ``` + #[inline] + pub fn mutex(this: &Self) -> &Arc> { + &this.lock + } +} + impl Drop for OwnedMutexGuard { fn drop(&mut self) { self.lock.s.release(1)