diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 732b6d217..7babb5293 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -95,7 +95,8 @@ impl<'a> TcpWriter<'a> { /// Flushes the written data to the socket. /// - /// This waits until all data has been sent, and ACKed by the remote host. + /// This waits until all data has been sent, and ACKed by the remote host. For a connection + /// closed with [`abort()`](TcpSocket::abort) it will wait for the TCP RST packet to be sent. pub async fn flush(&mut self) -> Result<(), Error> { self.io.flush().await } @@ -198,7 +199,8 @@ impl<'a> TcpSocket<'a> { /// Flushes the written data to the socket. /// - /// This waits until all data has been sent, and ACKed by the remote host. + /// This waits until all data has been sent, and ACKed by the remote host. For a connection + /// closed with [`abort()`](TcpSocket::abort) it will wait for the TCP RST packet to be sent. pub async fn flush(&mut self) -> Result<(), Error> { self.io.flush().await } @@ -262,6 +264,11 @@ impl<'a> TcpSocket<'a> { /// /// This instantly closes both the read and write halves of the socket. Any pending data /// that has not been sent will be lost. + /// + /// Note that the TCP RST packet is not sent immediately - if the `TcpSocket` is dropped too soon + /// the remote host may not know the connection has been closed. + /// `abort()` callers should wait for a [`flush()`](TcpSocket::flush) call to complete before + /// dropping or reusing the socket. pub fn abort(&mut self) { self.io.with_mut(|s, _| s.abort()) } @@ -347,9 +354,10 @@ impl<'d> TcpIo<'d> { async fn flush(&mut self) -> Result<(), Error> { poll_fn(move |cx| { self.with_mut(|s, _| { + let waiting_close = s.state() == tcp::State::Closed && s.remote_endpoint().is_some(); // If there are outstanding send operations, register for wake up and wait // smoltcp issues wake-ups when octets are dequeued from the send buffer - if s.send_queue() > 0 { + if s.send_queue() > 0 || waiting_close { s.register_send_waker(cx.waker()); Poll::Pending // No outstanding sends, socket is flushed