mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
io: read during write in copy_bidirectional
and copy
(#6532)
This commit is contained in:
parent
49609d073f
commit
3f397ccded
@ -96,12 +96,9 @@ impl CopyBuffer {
|
|||||||
// Keep track of task budget
|
// Keep track of task budget
|
||||||
let coop = ready!(crate::runtime::coop::poll_proceed(cx));
|
let coop = ready!(crate::runtime::coop::poll_proceed(cx));
|
||||||
loop {
|
loop {
|
||||||
// If our buffer is empty, then we need to read some data to
|
// If there is some space left in our buffer, then we try to read some
|
||||||
// continue.
|
// data to continue, thus maximizing the chances of a large write.
|
||||||
if self.pos == self.cap && !self.read_done {
|
if self.cap < self.buf.len() && !self.read_done {
|
||||||
self.pos = 0;
|
|
||||||
self.cap = 0;
|
|
||||||
|
|
||||||
match self.poll_fill_buf(cx, reader.as_mut()) {
|
match self.poll_fill_buf(cx, reader.as_mut()) {
|
||||||
Poll::Ready(Ok(())) => {
|
Poll::Ready(Ok(())) => {
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
@ -131,6 +128,9 @@ impl CopyBuffer {
|
|||||||
return Poll::Ready(Err(err));
|
return Poll::Ready(Err(err));
|
||||||
}
|
}
|
||||||
Poll::Pending => {
|
Poll::Pending => {
|
||||||
|
// Ignore pending reads when our buffer is not empty, because
|
||||||
|
// we can try to write data immediately.
|
||||||
|
if self.pos == self.cap {
|
||||||
// Try flushing when the reader has no progress to avoid deadlock
|
// Try flushing when the reader has no progress to avoid deadlock
|
||||||
// when the reader depends on buffered writer.
|
// when the reader depends on buffered writer.
|
||||||
if self.need_flush {
|
if self.need_flush {
|
||||||
@ -153,6 +153,7 @@ impl CopyBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If our buffer has some data, let's write it out!
|
// If our buffer has some data, let's write it out!
|
||||||
while self.pos < self.cap {
|
while self.pos < self.cap {
|
||||||
@ -188,9 +189,13 @@ impl CopyBuffer {
|
|||||||
"writer returned length larger than input slice"
|
"writer returned length larger than input slice"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// All data has been written, the buffer can be considered empty again
|
||||||
|
self.pos = 0;
|
||||||
|
self.cap = 0;
|
||||||
|
|
||||||
// If we've written all the data and we've seen EOF, flush out the
|
// If we've written all the data and we've seen EOF, flush out the
|
||||||
// data and finish the transfer.
|
// data and finish the transfer.
|
||||||
if self.pos == self.cap && self.read_done {
|
if self.read_done {
|
||||||
ready!(writer.as_mut().poll_flush(cx))?;
|
ready!(writer.as_mut().poll_flush(cx))?;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "fs",
|
feature = "fs",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user