From bd6f06d94cee95a8f691eb72f640ff03cc116d06 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Thu, 23 Sep 2021 11:41:42 +0800 Subject: [PATCH 1/3] sync: add blocking_lock for mutex Signed-off-by: hi-rustin --- tokio/src/sync/mutex.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tokio/src/sync/mutex.rs b/tokio/src/sync/mutex.rs index 6acd28b6255..fa3503f2fa1 100644 --- a/tokio/src/sync/mutex.rs +++ b/tokio/src/sync/mutex.rs @@ -301,6 +301,40 @@ impl Mutex { MutexGuard { lock: self } } + /// Blocking lock this mutex. When the lock has been acquired, function returns a + /// [`MutexGuard`]. + /// + /// This method is intended for use cases where you + /// need to use this mutex in asynchronous code as well as in synchronous code. + /// + /// # Examples + /// + /// ``` + /// use std::thread; + /// use std::sync::Arc; + /// use tokio::sync::Mutex; + /// + /// #[tokio::main] + /// async fn main() { + /// let mutex = Arc::new(Mutex::new(1)); + /// + /// let mutex1 = Arc::clone(&mutex); + /// let sync_code = thread::spawn(move || { + /// let mut n = mutex1.blocking_lock(); + /// *n = 2; + /// }); + /// + /// sync_code.join().unwrap(); + /// + /// let n = mutex.lock().await; + /// assert_eq!(*n, 2); + /// } + /// + /// ``` + pub fn blocking_lock(&self) -> MutexGuard<'_, T> { + crate::future::block_on(self.lock()) + } + /// Locks this mutex, causing the current task to yield until the lock has /// been acquired. When the lock has been acquired, this returns an /// [`OwnedMutexGuard`]. From 5d7a2f4c92593bd60e6bf60aed588f0850039621 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Thu, 23 Sep 2021 13:29:31 +0800 Subject: [PATCH 2/3] sync: add sync cfg Signed-off-by: hi-rustin --- tokio/src/sync/mutex.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tokio/src/sync/mutex.rs b/tokio/src/sync/mutex.rs index fa3503f2fa1..de566ad3052 100644 --- a/tokio/src/sync/mutex.rs +++ b/tokio/src/sync/mutex.rs @@ -331,6 +331,7 @@ impl Mutex { /// } /// /// ``` + #[cfg(feature = "sync")] pub fn blocking_lock(&self) -> MutexGuard<'_, T> { crate::future::block_on(self.lock()) } From 4a3ba2752e95b4791acca518e76f83fde282bf9e Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Thu, 23 Sep 2021 16:32:33 +0800 Subject: [PATCH 3/3] Use task spawn_blocking Signed-off-by: hi-rustin --- tokio/src/sync/mutex.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tokio/src/sync/mutex.rs b/tokio/src/sync/mutex.rs index de566ad3052..95b69e6281c 100644 --- a/tokio/src/sync/mutex.rs +++ b/tokio/src/sync/mutex.rs @@ -310,7 +310,6 @@ impl Mutex { /// # Examples /// /// ``` - /// use std::thread; /// use std::sync::Arc; /// use tokio::sync::Mutex; /// @@ -319,12 +318,12 @@ impl Mutex { /// let mutex = Arc::new(Mutex::new(1)); /// /// let mutex1 = Arc::clone(&mutex); - /// let sync_code = thread::spawn(move || { + /// let sync_code = tokio::task::spawn_blocking(move || { /// let mut n = mutex1.blocking_lock(); /// *n = 2; /// }); /// - /// sync_code.join().unwrap(); + /// sync_code.await.unwrap(); /// /// let n = mutex.lock().await; /// assert_eq!(*n, 2);