mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-20 00:00:08 +02:00
task: remove mutex in JoinError (#3959)
This commit is contained in:
@@ -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<Box<dyn Any + Send + 'static>>),
|
||||
Panic(SyncWrapper<Box<dyn Any + Send + 'static>>),
|
||||
}
|
||||
|
||||
impl JoinError {
|
||||
@@ -24,7 +25,7 @@ impl JoinError {
|
||||
|
||||
pub(crate) fn panic(err: Box<dyn Any + Send + 'static>) -> 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<Box<dyn Any + Send + 'static>, 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),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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! {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//! 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<T> {
|
||||
value: T,
|
||||
}
|
||||
|
||||
// safety: The SyncWrapper being send allows you to send the inner value across
|
||||
// thread boundaries.
|
||||
unsafe impl<T: Send> Send for SyncWrapper<T> {}
|
||||
|
||||
// safety: An immutable reference to a SyncWrapper is useless, so moving such an
|
||||
// immutable reference across threads is safe.
|
||||
unsafe impl<T> Sync for SyncWrapper<T> {}
|
||||
|
||||
impl<T> SyncWrapper<T> {
|
||||
pub(crate) fn new(value: T) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
|
||||
pub(crate) fn into_inner(self) -> T {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
@@ -452,6 +452,7 @@ assert_value!(tokio::task::LocalSet: !Send & !Sync & Unpin);
|
||||
assert_value!(tokio::task::JoinHandle<YY>: Send & Sync & Unpin);
|
||||
assert_value!(tokio::task::JoinHandle<YN>: Send & Sync & Unpin);
|
||||
assert_value!(tokio::task::JoinHandle<NN>: !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);
|
||||
|
||||
Reference in New Issue
Block a user