From deff2524c354d3d3038e1c3813032701946a5c68 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Mon, 25 Mar 2024 01:53:01 +0330 Subject: [PATCH] util: document cancel safety of `SinkExt::send` and `StreamExt::next` (#6417) --- tokio-util/src/codec/framed.rs | 11 +++++++++++ tokio-util/src/codec/framed_read.rs | 6 ++++++ tokio-util/src/codec/framed_write.rs | 7 +++++++ 3 files changed, 24 insertions(+) diff --git a/tokio-util/src/codec/framed.rs b/tokio-util/src/codec/framed.rs index e988da0a734..09a5b30b925 100644 --- a/tokio-util/src/codec/framed.rs +++ b/tokio-util/src/codec/framed.rs @@ -20,10 +20,21 @@ pin_project! { /// You can create a `Framed` instance by using the [`Decoder::framed`] adapter, or /// by using the `new` function seen below. /// + /// # Cancellation safety + /// + /// * [`futures_util::sink::SinkExt::send`]: if send is used as the event in a + /// `tokio::select!` statement and some other branch completes first, then it is + /// guaranteed that the message was not sent, but the message itself is lost. + /// * [`tokio_stream::StreamExt::next`]: This method is cancel safe. The returned + /// future only holds onto a reference to the underlying stream, so dropping it will + /// never lose a value. + /// /// [`Stream`]: futures_core::Stream /// [`Sink`]: futures_sink::Sink /// [`AsyncRead`]: tokio::io::AsyncRead /// [`Decoder::framed`]: crate::codec::Decoder::framed() + /// [`futures_util::sink::SinkExt::send`]: futures_util::sink::SinkExt::send + /// [`tokio_stream::StreamExt::next`]: https://docs.rs/tokio-stream/latest/tokio_stream/trait.StreamExt.html#method.next pub struct Framed { #[pin] inner: FramedImpl diff --git a/tokio-util/src/codec/framed_read.rs b/tokio-util/src/codec/framed_read.rs index 90ba5e7c9d0..3ede5876b57 100644 --- a/tokio-util/src/codec/framed_read.rs +++ b/tokio-util/src/codec/framed_read.rs @@ -17,9 +17,15 @@ pin_project! { /// For examples of how to use `FramedRead` with a codec, see the /// examples on the [`codec`] module. /// + /// # Cancellation safety + /// * [`tokio_stream::StreamExt::next`]: This method is cancel safe. The returned + /// future only holds onto a reference to the underlying stream, so dropping it will + /// never lose a value. + /// /// [`Stream`]: futures_core::Stream /// [`AsyncRead`]: tokio::io::AsyncRead /// [`codec`]: crate::codec + /// [`tokio_stream::StreamExt::next`]: https://docs.rs/tokio-stream/latest/tokio_stream/trait.StreamExt.html#method.next pub struct FramedRead { #[pin] inner: FramedImpl, diff --git a/tokio-util/src/codec/framed_write.rs b/tokio-util/src/codec/framed_write.rs index a7efaadd2b9..b2cab069c1f 100644 --- a/tokio-util/src/codec/framed_write.rs +++ b/tokio-util/src/codec/framed_write.rs @@ -18,8 +18,15 @@ pin_project! { /// For examples of how to use `FramedWrite` with a codec, see the /// examples on the [`codec`] module. /// + /// # Cancellation safety + /// + /// * [`futures_util::sink::SinkExt::send`]: if send is used as the event in a + /// `tokio::select!` statement and some other branch completes first, then it is + /// guaranteed that the message was not sent, but the message itself is lost. + /// /// [`Sink`]: futures_sink::Sink /// [`codec`]: crate::codec + /// [`futures_util::sink::SinkExt::send`]: futures_util::sink::SinkExt::send pub struct FramedWrite { #[pin] inner: FramedImpl,