From aac5227d6aaf09b75ad2241fcf5ce4e188212016 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 16 Aug 2024 20:23:25 +0200 Subject: [PATCH 1/3] Mark `Atomic*` `UnwindSafe` It's the same in the standard library. CC #4657. --- tokio/src/loom/std/atomic_u16.rs | 3 +++ tokio/src/loom/std/atomic_u32.rs | 3 +++ tokio/src/loom/std/atomic_usize.rs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/tokio/src/loom/std/atomic_u16.rs b/tokio/src/loom/std/atomic_u16.rs index dfc31f642a6..32ae349c33f 100644 --- a/tokio/src/loom/std/atomic_u16.rs +++ b/tokio/src/loom/std/atomic_u16.rs @@ -1,6 +1,7 @@ use std::cell::UnsafeCell; use std::fmt; use std::ops::Deref; +use std::panic; /// `AtomicU16` providing an additional `unsync_load` function. pub(crate) struct AtomicU16 { @@ -9,6 +10,8 @@ pub(crate) struct AtomicU16 { unsafe impl Send for AtomicU16 {} unsafe impl Sync for AtomicU16 {} +impl panic::RefUnwindSafe for AtomicU16 {} +impl panic::UnwindSafe for AtomicU16 {} impl AtomicU16 { pub(crate) const fn new(val: u16) -> AtomicU16 { diff --git a/tokio/src/loom/std/atomic_u32.rs b/tokio/src/loom/std/atomic_u32.rs index 94400176911..c34ca940f8a 100644 --- a/tokio/src/loom/std/atomic_u32.rs +++ b/tokio/src/loom/std/atomic_u32.rs @@ -1,6 +1,7 @@ use std::cell::UnsafeCell; use std::fmt; use std::ops::Deref; +use std::panic; /// `AtomicU32` providing an additional `unsync_load` function. pub(crate) struct AtomicU32 { @@ -9,6 +10,8 @@ pub(crate) struct AtomicU32 { unsafe impl Send for AtomicU32 {} unsafe impl Sync for AtomicU32 {} +impl panic::RefUnwindSafe for AtomicU32 {} +impl panic::UnwindSafe for AtomicU32 {} impl AtomicU32 { pub(crate) const fn new(val: u32) -> AtomicU32 { diff --git a/tokio/src/loom/std/atomic_usize.rs b/tokio/src/loom/std/atomic_usize.rs index 64605c76dd0..f88cc4bf727 100644 --- a/tokio/src/loom/std/atomic_usize.rs +++ b/tokio/src/loom/std/atomic_usize.rs @@ -1,6 +1,7 @@ use std::cell::UnsafeCell; use std::fmt; use std::ops; +use std::panic; /// `AtomicUsize` providing an additional `unsync_load` function. pub(crate) struct AtomicUsize { @@ -9,6 +10,8 @@ pub(crate) struct AtomicUsize { unsafe impl Send for AtomicUsize {} unsafe impl Sync for AtomicUsize {} +impl panic::RefUnwindSafe for AtomicUsize {} +impl panic::UnwindSafe for AtomicUsize {} impl AtomicUsize { pub(crate) const fn new(val: usize) -> AtomicUsize { From 0c4d2953610226f38fa3b8eb25c4793fcb2cd085 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 16 Aug 2024 20:34:29 +0200 Subject: [PATCH 2/3] Mark everything in `tokio::sync::mpsc` as `UnwindSafe` Since these types are safe in the face of panics and cannot cause data corruption, they're `UnwindSafe` irrespective of the channel's element type. CC #4657. --- tokio/src/sync/mpsc/chan.rs | 3 +++ tokio/tests/sync_mpsc.rs | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tokio/src/sync/mpsc/chan.rs b/tokio/src/sync/mpsc/chan.rs index 4006aa2b746..1edd2a755ae 100644 --- a/tokio/src/sync/mpsc/chan.rs +++ b/tokio/src/sync/mpsc/chan.rs @@ -9,6 +9,7 @@ use crate::sync::notify::Notify; use crate::util::cacheline::CachePadded; use std::fmt; +use std::panic; use std::process; use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release}; use std::task::Poll::{Pending, Ready}; @@ -108,6 +109,8 @@ impl fmt::Debug for RxFields { unsafe impl Send for Chan {} unsafe impl Sync for Chan {} +impl panic::RefUnwindSafe for Chan {} +impl panic::UnwindSafe for Chan {} pub(crate) fn channel(semaphore: S) -> (Tx, Rx) { let (tx, rx) = list::channel(); diff --git a/tokio/tests/sync_mpsc.rs b/tokio/tests/sync_mpsc.rs index cc88fa79972..97486e53763 100644 --- a/tokio/tests/sync_mpsc.rs +++ b/tokio/tests/sync_mpsc.rs @@ -11,6 +11,7 @@ use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test; use tokio::test as maybe_tokio_test; use std::fmt; +use std::panic; use std::sync::Arc; use tokio::sync::mpsc; use tokio::sync::mpsc::error::{TryRecvError, TrySendError}; @@ -26,6 +27,30 @@ trait AssertSend: Send {} impl AssertSend for mpsc::Sender {} impl AssertSend for mpsc::Receiver {} +#[allow(unused)] +trait AssertRefUnwindSafe: panic::RefUnwindSafe {} +impl AssertRefUnwindSafe for mpsc::OwnedPermit {} +impl<'a, T> AssertRefUnwindSafe for mpsc::Permit<'a, T> {} +impl<'a, T> AssertRefUnwindSafe for mpsc::PermitIterator<'a, T> {} +impl AssertRefUnwindSafe for mpsc::Receiver {} +impl AssertRefUnwindSafe for mpsc::Sender {} +impl AssertRefUnwindSafe for mpsc::UnboundedReceiver {} +impl AssertRefUnwindSafe for mpsc::UnboundedSender {} +impl AssertRefUnwindSafe for mpsc::WeakSender {} +impl AssertRefUnwindSafe for mpsc::WeakUnboundedSender {} + +#[allow(unused)] +trait AssertUnwindSafe: panic::UnwindSafe {} +impl AssertUnwindSafe for mpsc::OwnedPermit {} +impl<'a, T> AssertUnwindSafe for mpsc::Permit<'a, T> {} +impl<'a, T> AssertUnwindSafe for mpsc::PermitIterator<'a, T> {} +impl AssertUnwindSafe for mpsc::Receiver {} +impl AssertUnwindSafe for mpsc::Sender {} +impl AssertUnwindSafe for mpsc::UnboundedReceiver {} +impl AssertUnwindSafe for mpsc::UnboundedSender {} +impl AssertUnwindSafe for mpsc::WeakSender {} +impl AssertUnwindSafe for mpsc::WeakUnboundedSender {} + #[maybe_tokio_test] async fn send_recv_with_buffer() { let (tx, mut rx) = mpsc::channel::(16); From 28119ccf3dda91a8a716c5988e0312349d9707e5 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sun, 18 Aug 2024 12:39:25 +0200 Subject: [PATCH 3/3] Add missing tests for `Send`/`Sync`/`Unpin` in `mpsc` --- tokio/tests/async_send_sync.rs | 6 ++++++ tokio/tests/sync_mpsc.rs | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tokio/tests/async_send_sync.rs b/tokio/tests/async_send_sync.rs index 52b3835b753..0f578422bc0 100644 --- a/tokio/tests/async_send_sync.rs +++ b/tokio/tests/async_send_sync.rs @@ -413,6 +413,12 @@ assert_value!(tokio::sync::mpsc::UnboundedReceiver: Send & Sync & Unpin); assert_value!(tokio::sync::mpsc::UnboundedSender: !Send & !Sync & Unpin); assert_value!(tokio::sync::mpsc::UnboundedSender: Send & Sync & Unpin); assert_value!(tokio::sync::mpsc::UnboundedSender: Send & Sync & Unpin); +assert_value!(tokio::sync::mpsc::WeakSender: !Send & !Sync & Unpin); +assert_value!(tokio::sync::mpsc::WeakSender: Send & Sync & Unpin); +assert_value!(tokio::sync::mpsc::WeakSender: Send & Sync & Unpin); +assert_value!(tokio::sync::mpsc::WeakUnboundedSender: !Send & !Sync & Unpin); +assert_value!(tokio::sync::mpsc::WeakUnboundedSender: Send & Sync & Unpin); +assert_value!(tokio::sync::mpsc::WeakUnboundedSender: Send & Sync & Unpin); assert_value!(tokio::sync::mpsc::error::SendError: !Send & !Sync & Unpin); assert_value!(tokio::sync::mpsc::error::SendError: Send & !Sync & Unpin); assert_value!(tokio::sync::mpsc::error::SendError: Send & Sync & Unpin); diff --git a/tokio/tests/sync_mpsc.rs b/tokio/tests/sync_mpsc.rs index 97486e53763..3d91c5cf3e8 100644 --- a/tokio/tests/sync_mpsc.rs +++ b/tokio/tests/sync_mpsc.rs @@ -22,11 +22,6 @@ mod support { pub(crate) mod mpsc_stream; } -#[allow(unused)] -trait AssertSend: Send {} -impl AssertSend for mpsc::Sender {} -impl AssertSend for mpsc::Receiver {} - #[allow(unused)] trait AssertRefUnwindSafe: panic::RefUnwindSafe {} impl AssertRefUnwindSafe for mpsc::OwnedPermit {}