Skip to content

Commit 090d95d

Browse files
committed
Return StreamFut instead of stream, small code refactoring
1 parent 7dc39b0 commit 090d95d

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

futures-util/src/stream/stream/flat_map_unordered.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ impl ArcWake for PollWaker {
8585
}
8686

8787
/// Future which contains optional stream. If it's `Some`, it will attempt
88-
/// to call `poll_next` on it, returning `Some((item, stream))` in case of
89-
/// `Poll::Ready(Some(...))` or `None` in case of `Poll::Ready(None)`.
88+
/// to call `poll_next` on it, returning `Some((item, next_item_fut))` in
89+
/// case of `Poll::Ready(Some(...))` or `None` in case of `Poll::Ready(None)`.
9090
/// If `poll_next` will return `Poll::Pending`, it will be forwared to
9191
/// the future, and current task will be notified by waker.
9292
#[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -96,12 +96,19 @@ struct StreamFut<St> {
9696

9797
impl<St> StreamFut<St> {
9898
unsafe_pinned!(stream: Option<St>);
99+
100+
/// Constructs new `StreamFut` using given `stream`.
101+
fn new(stream: St) -> Self {
102+
Self {
103+
stream: stream.into(),
104+
}
105+
}
99106
}
100107

101108
impl<St: Stream + Unpin> Unpin for StreamFut<St> {}
102109

103110
impl<St: Stream> Future for StreamFut<St> {
104-
type Output = Option<(St::Item, St)>;
111+
type Output = Option<(St::Item, StreamFut<St>)>;
105112

106113
fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
107114
let item = if let Some(stream) = self.as_mut().stream().as_pin_mut() {
@@ -111,9 +118,12 @@ impl<St: Stream> Future for StreamFut<St> {
111118
};
112119

113120
Poll::Ready(item.map(|item| {
114-
(item, unsafe {
115-
self.get_unchecked_mut().stream.take().unwrap()
116-
})
121+
(
122+
item,
123+
StreamFut {
124+
stream: unsafe { self.get_unchecked_mut().stream.take() },
125+
},
126+
)
117127
}))
118128
}
119129
}
@@ -245,7 +255,7 @@ where
245255
impl<St, U, F> FusedStream for FlatMapUnordered<St, U, F>
246256
where
247257
St: FusedStream,
248-
U: Unpin + FusedStream,
258+
U: FusedStream,
249259
F: FnMut(St::Item) -> U,
250260
{
251261
fn is_terminated(&self) -> bool {
@@ -263,17 +273,15 @@ where
263273

264274
fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
265275
let mut poll_state_value = self.as_mut().poll_state().begin_polling();
266-
267276
let mut next_item = None;
268277
let mut need_to_poll_next = NONE;
269278
let mut polling_with_two_wakers =
270279
poll_state_value & NEED_TO_POLL == NEED_TO_POLL && self.not_exceeded_limit();
271-
let mut polled_stream = false;
272-
let mut polled_futures = false;
280+
let mut stream_will_be_woken = false;
281+
let mut futures_will_be_woken = false;
273282

274283
if poll_state_value & NEED_TO_POLL_STREAM != NONE {
275284
if self.not_exceeded_limit() {
276-
polled_stream = true;
277285
match if polling_with_two_wakers {
278286
let waker = self.create_poll_stream_waker(ctx);
279287
let mut ctx = Context::from_waker(&waker);
@@ -282,9 +290,7 @@ where
282290
self.as_mut().stream().poll_next(ctx)
283291
} {
284292
Poll::Ready(Some(inner_stream)) => {
285-
self.as_mut().futures().push(StreamFut {
286-
stream: Some(inner_stream),
287-
});
293+
self.as_mut().futures().push(StreamFut::new(inner_stream));
288294
need_to_poll_next |= NEED_TO_POLL_STREAM;
289295
// Polling futures in current iteration with the same context
290296
// is ok because we already received `Poll::Ready` from
@@ -300,6 +306,7 @@ where
300306
polling_with_two_wakers = false;
301307
}
302308
Poll::Pending => {
309+
stream_will_be_woken = true;
303310
if !polling_with_two_wakers {
304311
need_to_poll_next |= NEED_TO_POLL_STREAM;
305312
}
@@ -311,25 +318,23 @@ where
311318
}
312319

313320
if poll_state_value & NEED_TO_POLL_FUTURES != NONE {
314-
polled_futures = true;
315321
match if polling_with_two_wakers {
316322
let waker = self.create_poll_futures_waker(ctx);
317323
let mut ctx = Context::from_waker(&waker);
318324
self.as_mut().futures().poll_next(&mut ctx)
319325
} else {
320326
self.as_mut().futures().poll_next(ctx)
321327
} {
322-
Poll::Ready(Some(Some((item, stream)))) => {
323-
self.as_mut().futures().push(StreamFut {
324-
stream: Some(stream),
325-
});
328+
Poll::Ready(Some(Some((item, next_item_fut)))) => {
329+
self.as_mut().futures().push(next_item_fut);
326330
next_item = Some(item);
327331
need_to_poll_next |= NEED_TO_POLL_FUTURES;
328332
}
329333
Poll::Ready(Some(None)) => {
330334
need_to_poll_next |= NEED_TO_POLL_FUTURES;
331335
}
332336
Poll::Pending => {
337+
futures_will_be_woken = true;
333338
if !polling_with_two_wakers {
334339
need_to_poll_next |= NEED_TO_POLL_FUTURES;
335340
}
@@ -342,16 +347,12 @@ where
342347

343348
let poll_state_value = self.as_mut().poll_state().end_polling(need_to_poll_next);
344349

345-
if poll_state_value & NEED_TO_POLL != NONE {
346-
if !polling_with_two_wakers {
347-
if poll_state_value & NEED_TO_POLL_FUTURES != NONE && !polled_futures
348-
|| poll_state_value & NEED_TO_POLL_STREAM != NONE && !polled_stream
349-
{
350-
ctx.waker().wake_by_ref();
351-
}
352-
} else {
353-
ctx.waker().wake_by_ref();
354-
}
350+
if poll_state_value & NEED_TO_POLL != NONE
351+
&& (polling_with_two_wakers
352+
|| (poll_state_value & NEED_TO_POLL_FUTURES != NONE && !futures_will_be_woken
353+
|| poll_state_value & NEED_TO_POLL_STREAM != NONE && !stream_will_be_woken))
354+
{
355+
ctx.waker().wake_by_ref();
355356
}
356357

357358
if self.futures.is_empty() && self.is_stream_done || next_item.is_some() {

0 commit comments

Comments
 (0)