From f161f04515e57ec00a146618b8f7eb22bfcc5eac Mon Sep 17 00:00:00 2001 From: Zeeshan Ali Khan Date: Wed, 28 Dec 2022 00:08:22 +0100 Subject: [PATCH] join should yield item immediately if either stream is ready If one of the streams is ready and the other is pending, we should just return the item from the ready stream. Otherwise, join will never resolve until both streams are ready (which could be never). Fixes #12. --- src/join.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/join.rs b/src/join.rs index e6b845a..cc7b35b 100644 --- a/src/join.rs +++ b/src/join.rs @@ -275,17 +275,16 @@ where b.into() } - // If one side is pending, we can't return Ready until that gets resolved. Because we - // have already requested that our child streams wake us when it is possible to make - // any kind of progress, we meet the requirements to return Poll::Pending. - (PollState::Item(a, t), PollState::Pending) => { - *this.state = JoinState::A(a, t); - Poll::Pending - } - (PollState::Pending, PollState::Item(b, t)) => { - *this.state = JoinState::B(b, t); - Poll::Pending - } + // If one side is pending, return the ready one. Otherwise we can easily end up in the + // `Pending` state forever. + (PollState::Item(a, t), PollState::Pending) => Poll::Ready(PollResult::Item { + data: a, + ordering: t, + }), + (PollState::Pending, PollState::Item(b, t)) => Poll::Ready(PollResult::Item { + data: b, + ordering: t, + }), (PollState::Pending, PollState::Pending) => Poll::Pending, (PollState::Pending, PollState::NoneBefore) => Poll::Pending, (PollState::NoneBefore, PollState::Pending) => Poll::Pending,