Skip to content

Commit

Permalink
Mark everything in tokio::sync::mpsc as UnwindSafe
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tbu- committed Aug 16, 2024
1 parent 89d84b8 commit eb0b5a1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
3 changes: 3 additions & 0 deletions tokio/src/sync/mpsc/chan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -108,6 +109,8 @@ impl<T> fmt::Debug for RxFields<T> {

unsafe impl<T: Send, S: Send> Send for Chan<T, S> {}
unsafe impl<T: Send, S: Sync> Sync for Chan<T, S> {}
impl<T, S> panic::RefUnwindSafe for Chan<T, S> {}
impl<T, S> panic::UnwindSafe for Chan<T, S> {}

pub(crate) fn channel<T, S: Semaphore>(semaphore: S) -> (Tx<T, S>, Rx<T, S>) {
let (tx, rx) = list::channel();
Expand Down
31 changes: 30 additions & 1 deletion tokio/tests/sync_mpsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use tokio::test as maybe_tokio_test;

use std::fmt;
use std::sync::Arc;
use std::panic;
use tokio::sync::mpsc;
use tokio::sync::mpsc::error::{TryRecvError, TrySendError};
use tokio_test::*;
Expand All @@ -23,8 +24,36 @@ mod support {

#[allow(unused)]
trait AssertSend: Send {}
impl AssertSend for mpsc::Sender<i32> {}
impl AssertSend for mpsc::Receiver<i32> {}
impl AssertSend for mpsc::Sender<i32> {}
impl AssertSend for mpsc::UnboundedReceiver<i32> {}
impl AssertSend for mpsc::UnboundedSender<i32> {}
impl AssertSend for mpsc::WeakSender<i32> {}
impl AssertSend for mpsc::WeakUnboundedSender<i32> {}

#[allow(unused)]
trait AssertRefUnwindSafe: panic::RefUnwindSafe {}
impl<T> AssertRefUnwindSafe for mpsc::OwnedPermit<T> {}
impl<'a, T> AssertRefUnwindSafe for mpsc::Permit<'a, T> {}
impl<'a, T> AssertRefUnwindSafe for mpsc::PermitIterator<'a, T> {}
impl<T> AssertRefUnwindSafe for mpsc::Receiver<T> {}
impl<T> AssertRefUnwindSafe for mpsc::Sender<T> {}
impl<T> AssertRefUnwindSafe for mpsc::UnboundedReceiver<T> {}
impl<T> AssertRefUnwindSafe for mpsc::UnboundedSender<T> {}
impl<T> AssertRefUnwindSafe for mpsc::WeakSender<T> {}
impl<T> AssertRefUnwindSafe for mpsc::WeakUnboundedSender<T> {}

#[allow(unused)]
trait AssertUnwindSafe: panic::UnwindSafe {}
impl<T> AssertUnwindSafe for mpsc::OwnedPermit<T> {}
impl<'a, T> AssertUnwindSafe for mpsc::Permit<'a, T> {}
impl<'a, T> AssertUnwindSafe for mpsc::PermitIterator<'a, T> {}
impl<T> AssertUnwindSafe for mpsc::Receiver<T> {}
impl<T> AssertUnwindSafe for mpsc::Sender<T> {}
impl<T> AssertUnwindSafe for mpsc::UnboundedReceiver<T> {}
impl<T> AssertUnwindSafe for mpsc::UnboundedSender<T> {}
impl<T> AssertUnwindSafe for mpsc::WeakSender<T> {}
impl<T> AssertUnwindSafe for mpsc::WeakUnboundedSender<T> {}

#[maybe_tokio_test]
async fn send_recv_with_buffer() {
Expand Down

0 comments on commit eb0b5a1

Please sign in to comment.