diff options
| author | Anthony Grondin <[email protected]> | 2024-09-24 10:42:06 -0400 |
|---|---|---|
| committer | Anthony Grondin <[email protected]> | 2024-09-24 22:01:53 -0400 |
| commit | 712fa08363067d0a0e3ff07b3bd0633bee3ba07e (patch) | |
| tree | 9c3a067b56806bd426d1f3be910df074992e630e /embassy-net/src | |
| parent | e8da38772641ac19e5ded539144467efc9ed5a7b (diff) | |
feat(embassy-net): Implement `wait_read_ready()` + `wait_write_ready()` for TcpSocket
Diffstat (limited to 'embassy-net/src')
| -rw-r--r-- | embassy-net/src/tcp.rs | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index fc66d6192..8fdad01cc 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | use core::future::poll_fn; | 11 | use core::future::poll_fn; |
| 12 | use core::mem; | 12 | use core::mem; |
| 13 | use core::task::Poll; | 13 | use core::task::{Context, Poll}; |
| 14 | 14 | ||
| 15 | use embassy_time::Duration; | 15 | use embassy_time::Duration; |
| 16 | use smoltcp::iface::{Interface, SocketHandle}; | 16 | use smoltcp::iface::{Interface, SocketHandle}; |
| @@ -274,6 +274,16 @@ impl<'a> TcpSocket<'a> { | |||
| 274 | .await | 274 | .await |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | /// Wait until the socket becomes readable. | ||
| 278 | /// | ||
| 279 | /// A socket becomes readable when the receive half of the full-duplex connection is open | ||
| 280 | /// (see [may_recv](#method.may_recv)), and there is some pending data in the receive buffer. | ||
| 281 | /// | ||
| 282 | /// This is the equivalent of [read](#method.read), without buffering any data. | ||
| 283 | pub async fn wait_read_ready(&self) { | ||
| 284 | poll_fn(move |cx| self.io.poll_read_ready(cx)).await | ||
| 285 | } | ||
| 286 | |||
| 277 | /// Read data from the socket. | 287 | /// Read data from the socket. |
| 278 | /// | 288 | /// |
| 279 | /// Returns how many bytes were read, or an error. If no data is available, it waits | 289 | /// Returns how many bytes were read, or an error. If no data is available, it waits |
| @@ -285,6 +295,16 @@ impl<'a> TcpSocket<'a> { | |||
| 285 | self.io.read(buf).await | 295 | self.io.read(buf).await |
| 286 | } | 296 | } |
| 287 | 297 | ||
| 298 | /// Wait until the socket becomes writable. | ||
| 299 | /// | ||
| 300 | /// A socket becomes writable when the transmit half of the full-duplex connection is open | ||
| 301 | /// (see [may_send](#method.may_send)), and the transmit buffer is not full. | ||
| 302 | /// | ||
| 303 | /// This is the equivalent of [write](#method.write), without sending any data. | ||
| 304 | pub async fn wait_write_ready(&self) { | ||
| 305 | poll_fn(move |cx| self.io.poll_write_ready(cx)).await | ||
| 306 | } | ||
| 307 | |||
| 288 | /// Write data to the socket. | 308 | /// Write data to the socket. |
| 289 | /// | 309 | /// |
| 290 | /// Returns how many bytes were written, or an error. If the socket is not ready to | 310 | /// Returns how many bytes were written, or an error. If the socket is not ready to |
| @@ -441,7 +461,7 @@ impl<'d> TcpIo<'d> { | |||
| 441 | }) | 461 | }) |
| 442 | } | 462 | } |
| 443 | 463 | ||
| 444 | fn with_mut<R>(&mut self, f: impl FnOnce(&mut tcp::Socket, &mut Interface) -> R) -> R { | 464 | fn with_mut<R>(&self, f: impl FnOnce(&mut tcp::Socket, &mut Interface) -> R) -> R { |
| 445 | self.stack.with_mut(|i| { | 465 | self.stack.with_mut(|i| { |
| 446 | let socket = i.sockets.get_mut::<tcp::Socket>(self.handle); | 466 | let socket = i.sockets.get_mut::<tcp::Socket>(self.handle); |
| 447 | let res = f(socket, &mut i.iface); | 467 | let res = f(socket, &mut i.iface); |
| @@ -450,6 +470,17 @@ impl<'d> TcpIo<'d> { | |||
| 450 | }) | 470 | }) |
| 451 | } | 471 | } |
| 452 | 472 | ||
| 473 | fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<()> { | ||
| 474 | self.with_mut(|s, _| { | ||
| 475 | if s.can_recv() { | ||
| 476 | Poll::Ready(()) | ||
| 477 | } else { | ||
| 478 | s.register_recv_waker(cx.waker()); | ||
| 479 | Poll::Pending | ||
| 480 | } | ||
| 481 | }) | ||
| 482 | } | ||
| 483 | |||
| 453 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 484 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
| 454 | poll_fn(move |cx| { | 485 | poll_fn(move |cx| { |
| 455 | // CAUTION: smoltcp semantics around EOF are different to what you'd expect | 486 | // CAUTION: smoltcp semantics around EOF are different to what you'd expect |
| @@ -478,6 +509,17 @@ impl<'d> TcpIo<'d> { | |||
| 478 | .await | 509 | .await |
| 479 | } | 510 | } |
| 480 | 511 | ||
| 512 | fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<()> { | ||
| 513 | self.with_mut(|s, _| { | ||
| 514 | if s.can_send() { | ||
| 515 | Poll::Ready(()) | ||
| 516 | } else { | ||
| 517 | s.register_send_waker(cx.waker()); | ||
| 518 | Poll::Pending | ||
| 519 | } | ||
| 520 | }) | ||
| 521 | } | ||
| 522 | |||
| 481 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | 523 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { |
| 482 | poll_fn(move |cx| { | 524 | poll_fn(move |cx| { |
| 483 | self.with_mut(|s, _| match s.send_slice(buf) { | 525 | self.with_mut(|s, _| match s.send_slice(buf) { |
