mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00
io: simplify split check (#2144)
* io: Clean up split check * fix tests
This commit is contained in:
parent
38bff0adda
commit
c7719a2d29
@ -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<T> {
|
struct Inner<T> {
|
||||||
locked: AtomicBool,
|
locked: AtomicBool,
|
||||||
stream: UnsafeCell<T>,
|
stream: UnsafeCell<T>,
|
||||||
@ -73,16 +61,10 @@ struct Guard<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ReadHalf<T> {
|
impl<T> ReadHalf<T> {
|
||||||
/// Get an opaque ID for the parent stream.
|
/// Check if this `ReadHalf` and some `WriteHalf` were split from the same
|
||||||
///
|
/// stream.
|
||||||
/// This can be used to check if two halves have been split from the
|
pub fn is_pair_of(&self, other: &WriteHalf<T>) -> bool {
|
||||||
/// same stream.
|
other.is_pair_of(&self)
|
||||||
/// 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<T> as usize)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reunite with a previously split `WriteHalf`.
|
/// Reunite with a previously split `WriteHalf`.
|
||||||
@ -94,7 +76,7 @@ impl<T> ReadHalf<T> {
|
|||||||
/// This can be checked ahead of time by comparing the stream ID
|
/// This can be checked ahead of time by comparing the stream ID
|
||||||
/// of the two halves.
|
/// of the two halves.
|
||||||
pub fn unsplit(self, wr: WriteHalf<T>) -> T {
|
pub fn unsplit(self, wr: WriteHalf<T>) -> T {
|
||||||
if self.stream_id() == wr.stream_id() {
|
if self.is_pair_of(&wr) {
|
||||||
drop(wr);
|
drop(wr);
|
||||||
|
|
||||||
let inner = Arc::try_unwrap(self.inner)
|
let inner = Arc::try_unwrap(self.inner)
|
||||||
@ -109,16 +91,10 @@ impl<T> ReadHalf<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> WriteHalf<T> {
|
impl<T> WriteHalf<T> {
|
||||||
/// Get an opaque ID for the parent stream.
|
/// Check if this `WriteHalf` and some `ReadHalf` were split from the same
|
||||||
///
|
/// stream.
|
||||||
/// This can be used to check if two halves have been split from the
|
pub fn is_pair_of(&self, other: &ReadHalf<T>) -> bool {
|
||||||
/// same stream.
|
Arc::ptr_eq(&self.inner, &other.inner)
|
||||||
/// 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<T> as usize)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,10 +49,10 @@ fn is_send_and_sync() {
|
|||||||
fn split_stream_id() {
|
fn split_stream_id() {
|
||||||
let (r1, w1) = split(RW);
|
let (r1, w1) = split(RW);
|
||||||
let (r2, w2) = split(RW);
|
let (r2, w2) = split(RW);
|
||||||
assert_eq!(r1.stream_id(), w1.stream_id());
|
assert_eq!(r1.is_pair_of(&w1), true);
|
||||||
assert_eq!(r1.stream_id(), w1.stream_id());
|
assert_eq!(r1.is_pair_of(&w2), false);
|
||||||
assert_ne!(r1.stream_id(), w2.stream_id());
|
assert_eq!(r2.is_pair_of(&w2), true);
|
||||||
assert_ne!(r2.stream_id(), w1.stream_id());
|
assert_eq!(r2.is_pair_of(&w1), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user