diff --git a/tokio/src/io/split.rs b/tokio/src/io/split.rs index e56e6ee95dc..2572a786634 100644 --- a/tokio/src/io/split.rs +++ b/tokio/src/io/split.rs @@ -51,18 +51,6 @@ cfg_io_util! { } } -/// An opaque ID for the parent stream of a split half. -/// -/// If you keep a `SplitStreamId` around after both halves have been dropped or reunited, -/// the stream ID is dangling. -/// The same ID may then be used for other split streams. -/// To avoid this, do not keep `SplitStreamId` around after both half have been dropped. -/// -/// Note that it is still impossible to unsplit two halves from a different stream, -/// since at-least one half has not been dropped in that scenario. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct SplitStreamId(usize); - struct Inner { locked: AtomicBool, stream: UnsafeCell, @@ -73,16 +61,10 @@ struct Guard<'a, T> { } impl ReadHalf { - /// Get an opaque ID for the parent stream. - /// - /// This can be used to check if two halves have been split from the - /// same stream. - /// The stream ID can also be used as key in associative containers. - /// - /// Note that stream IDs may dangle when both halves are dropped. - /// See [`SplitStreamId`] for more information. - pub fn stream_id(&self) -> SplitStreamId { - SplitStreamId(&*self.inner as *const Inner as usize) + /// Check if this `ReadHalf` and some `WriteHalf` were split from the same + /// stream. + pub fn is_pair_of(&self, other: &WriteHalf) -> bool { + other.is_pair_of(&self) } /// Reunite with a previously split `WriteHalf`. @@ -94,7 +76,7 @@ impl ReadHalf { /// This can be checked ahead of time by comparing the stream ID /// of the two halves. pub fn unsplit(self, wr: WriteHalf) -> T { - if self.stream_id() == wr.stream_id() { + if self.is_pair_of(&wr) { drop(wr); let inner = Arc::try_unwrap(self.inner) @@ -109,16 +91,10 @@ impl ReadHalf { } impl WriteHalf { - /// Get an opaque ID for the parent stream. - /// - /// This can be used to check if two halves have been split from the - /// same stream. - /// The stream ID can also be used as key in associative containers. - /// - /// Note that stream IDs may dangle when both halves are dropped. - /// See [`SplitStreamId`] for more information. - pub fn stream_id(&self) -> SplitStreamId { - SplitStreamId(&*self.inner as *const Inner as usize) + /// Check if this `WriteHalf` and some `ReadHalf` were split from the same + /// stream. + pub fn is_pair_of(&self, other: &ReadHalf) -> bool { + Arc::ptr_eq(&self.inner, &other.inner) } } diff --git a/tokio/tests/io_split.rs b/tokio/tests/io_split.rs index f6326ae9b7e..e54bf248521 100644 --- a/tokio/tests/io_split.rs +++ b/tokio/tests/io_split.rs @@ -49,10 +49,10 @@ fn is_send_and_sync() { fn split_stream_id() { let (r1, w1) = split(RW); let (r2, w2) = split(RW); - assert_eq!(r1.stream_id(), w1.stream_id()); - assert_eq!(r1.stream_id(), w1.stream_id()); - assert_ne!(r1.stream_id(), w2.stream_id()); - assert_ne!(r2.stream_id(), w1.stream_id()); + assert_eq!(r1.is_pair_of(&w1), true); + assert_eq!(r1.is_pair_of(&w2), false); + assert_eq!(r2.is_pair_of(&w2), true); + assert_eq!(r2.is_pair_of(&w1), false); } #[test]