mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-29 00:00:11 +02:00
io: use poll_fn in copy_bidirectional (#5486)
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
use super::copy::CopyBuffer;
|
use super::copy::CopyBuffer;
|
||||||
|
|
||||||
|
use crate::future::poll_fn;
|
||||||
use crate::io::{AsyncRead, AsyncWrite};
|
use crate::io::{AsyncRead, AsyncWrite};
|
||||||
|
|
||||||
use std::future::Future;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@@ -13,13 +13,6 @@ enum TransferState {
|
|||||||
Done(u64),
|
Done(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CopyBidirectional<'a, A: ?Sized, B: ?Sized> {
|
|
||||||
a: &'a mut A,
|
|
||||||
b: &'a mut B,
|
|
||||||
a_to_b: TransferState,
|
|
||||||
b_to_a: TransferState,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transfer_one_direction<A, B>(
|
fn transfer_one_direction<A, B>(
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
state: &mut TransferState,
|
state: &mut TransferState,
|
||||||
@@ -48,35 +41,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, A, B> Future for CopyBidirectional<'a, A, B>
|
|
||||||
where
|
|
||||||
A: AsyncRead + AsyncWrite + Unpin + ?Sized,
|
|
||||||
B: AsyncRead + AsyncWrite + Unpin + ?Sized,
|
|
||||||
{
|
|
||||||
type Output = io::Result<(u64, u64)>;
|
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
// Unpack self into mut refs to each field to avoid borrow check issues.
|
|
||||||
let CopyBidirectional {
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
a_to_b,
|
|
||||||
b_to_a,
|
|
||||||
} = &mut *self;
|
|
||||||
|
|
||||||
let a_to_b = transfer_one_direction(cx, a_to_b, &mut *a, &mut *b)?;
|
|
||||||
let b_to_a = transfer_one_direction(cx, b_to_a, &mut *b, &mut *a)?;
|
|
||||||
|
|
||||||
// It is not a problem if ready! returns early because transfer_one_direction for the
|
|
||||||
// other direction will keep returning TransferState::Done(count) in future calls to poll
|
|
||||||
let a_to_b = ready!(a_to_b);
|
|
||||||
let b_to_a = ready!(b_to_a);
|
|
||||||
|
|
||||||
Poll::Ready(Ok((a_to_b, b_to_a)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copies data in both directions between `a` and `b`.
|
/// Copies data in both directions between `a` and `b`.
|
||||||
///
|
///
|
||||||
/// This function returns a future that will read from both streams,
|
/// This function returns a future that will read from both streams,
|
||||||
@@ -110,11 +74,18 @@ where
|
|||||||
A: AsyncRead + AsyncWrite + Unpin + ?Sized,
|
A: AsyncRead + AsyncWrite + Unpin + ?Sized,
|
||||||
B: AsyncRead + AsyncWrite + Unpin + ?Sized,
|
B: AsyncRead + AsyncWrite + Unpin + ?Sized,
|
||||||
{
|
{
|
||||||
CopyBidirectional {
|
let mut a_to_b = TransferState::Running(CopyBuffer::new());
|
||||||
a,
|
let mut b_to_a = TransferState::Running(CopyBuffer::new());
|
||||||
b,
|
poll_fn(|cx| {
|
||||||
a_to_b: TransferState::Running(CopyBuffer::new()),
|
let a_to_b = transfer_one_direction(cx, &mut a_to_b, a, b)?;
|
||||||
b_to_a: TransferState::Running(CopyBuffer::new()),
|
let b_to_a = transfer_one_direction(cx, &mut b_to_a, b, a)?;
|
||||||
}
|
|
||||||
|
// It is not a problem if ready! returns early because transfer_one_direction for the
|
||||||
|
// other direction will keep returning TransferState::Done(count) in future calls to poll
|
||||||
|
let a_to_b = ready!(a_to_b);
|
||||||
|
let b_to_a = ready!(b_to_a);
|
||||||
|
|
||||||
|
Poll::Ready(Ok((a_to_b, b_to_a)))
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user