mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
tokio-util: stop polling StreamReader after EOF (#8332)
This commit is contained in:
@@ -158,6 +158,7 @@ pub struct StreamReader<S, B> {
|
||||
inner: S,
|
||||
// This field is not pinned.
|
||||
chunk: Option<B>,
|
||||
eof: bool,
|
||||
}
|
||||
|
||||
impl<S, B, E> StreamReader<S, B>
|
||||
@@ -179,6 +180,7 @@ where
|
||||
Self {
|
||||
inner: stream,
|
||||
chunk: None,
|
||||
eof: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +279,8 @@ where
|
||||
// This unwrap is very sad, but it can't be avoided.
|
||||
let buf = self.project().chunk.as_ref().unwrap().chunk();
|
||||
return Poll::Ready(Ok(buf));
|
||||
} else if *self.as_mut().project().eof {
|
||||
return Poll::Ready(Ok(&[]));
|
||||
} else {
|
||||
match self.as_mut().project().inner.poll_next(cx) {
|
||||
Poll::Ready(Some(Ok(chunk))) => {
|
||||
@@ -284,7 +288,10 @@ where
|
||||
*self.as_mut().project().chunk = Some(chunk);
|
||||
}
|
||||
Poll::Ready(Some(Err(err))) => return Poll::Ready(Err(err.into())),
|
||||
Poll::Ready(None) => return Poll::Ready(Ok(&[])),
|
||||
Poll::Ready(None) => {
|
||||
*self.as_mut().project().eof = true;
|
||||
return Poll::Ready(Ok(&[]));
|
||||
}
|
||||
Poll::Pending => return Poll::Pending,
|
||||
}
|
||||
}
|
||||
@@ -311,6 +318,7 @@ impl<S: Unpin, B> Unpin for StreamReader<S, B> {}
|
||||
struct StreamReaderProject<'a, S, B> {
|
||||
inner: Pin<&'a mut S>,
|
||||
chunk: &'a mut Option<B>,
|
||||
eof: &'a mut bool,
|
||||
}
|
||||
|
||||
impl<S, B> StreamReader<S, B> {
|
||||
@@ -322,6 +330,7 @@ impl<S, B> StreamReader<S, B> {
|
||||
StreamReaderProject {
|
||||
inner: unsafe { Pin::new_unchecked(&mut me.inner) },
|
||||
chunk: &mut me.chunk,
|
||||
eof: &mut me.eof,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user