From 73c66412b3c26bdc08b2f8886a20f5e13847fecf Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 30 Aug 2019 19:10:37 +0900 Subject: [PATCH] Add Mutex::{get_mut, into_inner} --- futures-util/src/lock/mutex.rs | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/futures-util/src/lock/mutex.rs b/futures-util/src/lock/mutex.rs index 832e75aff1..7e679782e9 100644 --- a/futures-util/src/lock/mutex.rs +++ b/futures-util/src/lock/mutex.rs @@ -67,10 +67,24 @@ impl Mutex { pub fn new(t: T) -> Mutex { Mutex { state: AtomicUsize::new(0), - value: UnsafeCell::new(t), waiters: StdMutex::new(Slab::new()), + value: UnsafeCell::new(t), } } + + /// Consumes this mutex, returning the underlying data. + /// + /// # Examples + /// + /// ``` + /// use futures::lock::Mutex; + /// + /// let mutex = Mutex::new(0); + /// assert_eq!(mutex.into_inner(), 0); + /// ``` + pub fn into_inner(self) -> T { + self.value.into_inner() + } } impl Mutex { @@ -97,6 +111,28 @@ impl Mutex { } } + /// Returns a mutable reference to the underlying data. + /// + /// Since this call borrows the `Mutex` mutably, no actual locking needs to + /// take place -- the mutable borrow statically guarantees no locks exist. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::lock::Mutex; + /// + /// let mut mutex = Mutex::new(0); + /// *mutex.get_mut() = 10; + /// assert_eq!(*mutex.lock().await, 10); + /// # }); + /// ``` + pub fn get_mut(&mut self) -> &mut T { + // We know statically that there are no other references to `self`, so + // there's no need to lock the inner mutex. + unsafe { &mut *self.value.get() } + } + fn remove_waker(&self, wait_key: usize, wake_another: bool) { if wait_key != WAIT_KEY_NONE { let mut waiters = self.waiters.lock().unwrap();