From b51e056e74874d2429b444751f4d2a16b10d92eb Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 14 Jul 2021 11:33:11 +0200 Subject: [PATCH 1/3] task: remove mutex in JoinError --- tokio/src/runtime/task/error.rs | 9 +++++---- tokio/src/util/mod.rs | 3 +++ tokio/src/util/sync_wrapper.rs | 28 ++++++++++++++++++++++++++++ tokio/tests/async_send_sync.rs | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tokio/src/util/sync_wrapper.rs diff --git a/tokio/src/runtime/task/error.rs b/tokio/src/runtime/task/error.rs index 177fe65e9b9..17fb09390ae 100644 --- a/tokio/src/runtime/task/error.rs +++ b/tokio/src/runtime/task/error.rs @@ -1,7 +1,8 @@ use std::any::Any; use std::fmt; use std::io; -use std::sync::Mutex; + +use crate::util::SyncWrapper; cfg_rt! { /// Task failed to execute to completion. @@ -12,7 +13,7 @@ cfg_rt! { enum Repr { Cancelled, - Panic(Mutex>), + Panic(SyncWrapper>), } impl JoinError { @@ -24,7 +25,7 @@ impl JoinError { pub(crate) fn panic(err: Box) -> JoinError { JoinError { - repr: Repr::Panic(Mutex::new(err)), + repr: Repr::Panic(SyncWrapper::new(err)), } } @@ -106,7 +107,7 @@ impl JoinError { /// ``` pub fn try_into_panic(self) -> Result, JoinError> { match self.repr { - Repr::Panic(p) => Ok(p.into_inner().expect("Extracting panic from mutex")), + Repr::Panic(p) => Ok(p.into_inner()), _ => Err(self), } } diff --git a/tokio/src/util/mod.rs b/tokio/src/util/mod.rs index b267125b15b..bcc73ed68de 100644 --- a/tokio/src/util/mod.rs +++ b/tokio/src/util/mod.rs @@ -21,6 +21,9 @@ cfg_rt! { mod wake; pub(crate) use wake::WakerRef; pub(crate) use wake::{waker_ref, Wake}; + + mod sync_wrapper; + pub(crate) use sync_wrapper::SyncWrapper; } cfg_rt_multi_thread! { diff --git a/tokio/src/util/sync_wrapper.rs b/tokio/src/util/sync_wrapper.rs new file mode 100644 index 00000000000..6d6f5e57c4c --- /dev/null +++ b/tokio/src/util/sync_wrapper.rs @@ -0,0 +1,28 @@ +//! This module contains a type that can make `Send + !Sync` types `Sync` by +//! disallowing all immutable access to the value. +//! +//! A similar primitive is provided in the `sync_wrapper` crate. + +pub(crate) struct SyncWrapper { + value: T, +} + +// safety: The SyncWrapper being send allows you to send the inner value across +// thread boundaries. +unsafe impl Send for SyncWrapper {} + +// safety: An immutable reference to a SyncWrapper is useless, so moving such an +// immutable reference across threads is safe. +unsafe impl Sync for SyncWrapper {} + +impl SyncWrapper { + pub(crate) fn new(value: T) -> Self { + Self { + value, + } + } + + pub(crate) fn into_inner(self) -> T { + self.value + } +} diff --git a/tokio/tests/async_send_sync.rs b/tokio/tests/async_send_sync.rs index 12d13239387..97118ce66dc 100644 --- a/tokio/tests/async_send_sync.rs +++ b/tokio/tests/async_send_sync.rs @@ -452,6 +452,7 @@ assert_value!(tokio::task::LocalSet: !Send & !Sync & Unpin); assert_value!(tokio::task::JoinHandle: Send & Sync & Unpin); assert_value!(tokio::task::JoinHandle: Send & Sync & Unpin); assert_value!(tokio::task::JoinHandle: !Send & !Sync & Unpin); +assert_value!(tokio::task::JoinError: Send & Sync & Unpin); assert_value!(tokio::runtime::Builder: Send & Sync & Unpin); assert_value!(tokio::runtime::EnterGuard<'_>: Send & Sync & Unpin); From e8d1be8a3bafef8cc534b8d505331da69c4836a8 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 14 Jul 2021 11:45:53 +0200 Subject: [PATCH 2/3] rustfmt --- tokio/src/util/sync_wrapper.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tokio/src/util/sync_wrapper.rs b/tokio/src/util/sync_wrapper.rs index 6d6f5e57c4c..5ffc8f96b16 100644 --- a/tokio/src/util/sync_wrapper.rs +++ b/tokio/src/util/sync_wrapper.rs @@ -17,9 +17,7 @@ unsafe impl Sync for SyncWrapper {} impl SyncWrapper { pub(crate) fn new(value: T) -> Self { - Self { - value, - } + Self { value } } pub(crate) fn into_inner(self) -> T { From bef7127aea0d615f2181a80a2a2305b3a6fc25d8 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 14 Jul 2021 11:50:04 +0200 Subject: [PATCH 3/3] poke ci