mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-10-02 14:44:32 +00:00
Merge pull request #3804 from Easyoakland/fix-udp-send
Return Truncate error instead of looping forever on udp send.
This commit is contained in:
commit
7ec0b30484
@ -21,7 +21,7 @@ pub enum BindError {
|
|||||||
NoRoute,
|
NoRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error returned by [`UdpSocket::recv_from`] and [`UdpSocket::send_to`].
|
/// Error returned by [`UdpSocket::send_to`].
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum SendError {
|
pub enum SendError {
|
||||||
@ -29,9 +29,11 @@ pub enum SendError {
|
|||||||
NoRoute,
|
NoRoute,
|
||||||
/// Socket not bound to an outgoing port.
|
/// Socket not bound to an outgoing port.
|
||||||
SocketNotBound,
|
SocketNotBound,
|
||||||
|
/// There is not enough transmit buffer capacity to ever send this packet.
|
||||||
|
PacketTooLarge,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error returned by [`UdpSocket::recv_from`] and [`UdpSocket::send_to`].
|
/// Error returned by [`UdpSocket::recv_from`].
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum RecvError {
|
pub enum RecvError {
|
||||||
@ -224,6 +226,8 @@ impl<'a> UdpSocket<'a> {
|
|||||||
///
|
///
|
||||||
/// This method will wait until the datagram has been sent.
|
/// This method will wait until the datagram has been sent.
|
||||||
///
|
///
|
||||||
|
/// If the socket's send buffer is too small to fit `buf`, this method will return `Poll::Ready(Err(SendError::Truncated))`
|
||||||
|
///
|
||||||
/// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)`
|
/// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)`
|
||||||
pub async fn send_to<T>(&self, buf: &[u8], remote_endpoint: T) -> Result<(), SendError>
|
pub async fn send_to<T>(&self, buf: &[u8], remote_endpoint: T) -> Result<(), SendError>
|
||||||
where
|
where
|
||||||
@ -240,11 +244,19 @@ impl<'a> UdpSocket<'a> {
|
|||||||
/// When the socket's send buffer is full, this method will return `Poll::Pending`
|
/// When the socket's send buffer is full, this method will return `Poll::Pending`
|
||||||
/// and register the current task to be notified when the buffer has space available.
|
/// and register the current task to be notified when the buffer has space available.
|
||||||
///
|
///
|
||||||
|
/// If the socket's send buffer is too small to fit `buf`, this method will return `Poll::Ready(Err(SendError::Truncated))`
|
||||||
|
///
|
||||||
/// When the remote endpoint is not reachable, this method will return `Poll::Ready(Err(Error::NoRoute))`.
|
/// When the remote endpoint is not reachable, this method will return `Poll::Ready(Err(Error::NoRoute))`.
|
||||||
pub fn poll_send_to<T>(&self, buf: &[u8], remote_endpoint: T, cx: &mut Context<'_>) -> Poll<Result<(), SendError>>
|
pub fn poll_send_to<T>(&self, buf: &[u8], remote_endpoint: T, cx: &mut Context<'_>) -> Poll<Result<(), SendError>>
|
||||||
where
|
where
|
||||||
T: Into<UdpMetadata>,
|
T: Into<UdpMetadata>,
|
||||||
{
|
{
|
||||||
|
// Don't need to wake waker in `with_mut` if the buffer will never fit the udp tx_buffer.
|
||||||
|
let send_capacity_too_small = self.with(|s, _| s.payload_send_capacity() < buf.len());
|
||||||
|
if send_capacity_too_small {
|
||||||
|
return Poll::Ready(Err(SendError::PacketTooLarge));
|
||||||
|
}
|
||||||
|
|
||||||
self.with_mut(|s, _| match s.send_slice(buf, remote_endpoint) {
|
self.with_mut(|s, _| match s.send_slice(buf, remote_endpoint) {
|
||||||
// Entire datagram has been sent
|
// Entire datagram has been sent
|
||||||
Ok(()) => Poll::Ready(Ok(())),
|
Ok(()) => Poll::Ready(Ok(())),
|
||||||
@ -268,12 +280,20 @@ impl<'a> UdpSocket<'a> {
|
|||||||
/// This method will wait until the buffer can fit the requested size before
|
/// This method will wait until the buffer can fit the requested size before
|
||||||
/// calling the function to fill its contents.
|
/// calling the function to fill its contents.
|
||||||
///
|
///
|
||||||
|
/// If the socket's send buffer is too small to fit `size`, this method will return `Poll::Ready(Err(SendError::Truncated))`
|
||||||
|
///
|
||||||
/// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)`
|
/// When the remote endpoint is not reachable, this method will return `Err(SendError::NoRoute)`
|
||||||
pub async fn send_to_with<T, F, R>(&mut self, size: usize, remote_endpoint: T, f: F) -> Result<R, SendError>
|
pub async fn send_to_with<T, F, R>(&mut self, size: usize, remote_endpoint: T, f: F) -> Result<R, SendError>
|
||||||
where
|
where
|
||||||
T: Into<UdpMetadata> + Copy,
|
T: Into<UdpMetadata> + Copy,
|
||||||
F: FnOnce(&mut [u8]) -> R,
|
F: FnOnce(&mut [u8]) -> R,
|
||||||
{
|
{
|
||||||
|
// Don't need to wake waker in `with_mut` if the buffer will never fit the udp tx_buffer.
|
||||||
|
let send_capacity_too_small = self.with(|s, _| s.payload_send_capacity() < size);
|
||||||
|
if send_capacity_too_small {
|
||||||
|
return Err(SendError::PacketTooLarge);
|
||||||
|
}
|
||||||
|
|
||||||
let mut f = Some(f);
|
let mut f = Some(f);
|
||||||
poll_fn(move |cx| {
|
poll_fn(move |cx| {
|
||||||
self.with_mut(|s, _| {
|
self.with_mut(|s, _| {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user