[pulseaudio-discuss] [PATCH]raop2: Blocking UDP sockets

Hajime Fujita crisp.fujita at nifty.com
Fri Sep 13 21:02:15 PDT 2013


Hi Matthias,

Thank you for the patch.

However, I don't it's a good idea to do a busy loop here, because
1) it would consume 100% of the CPU time
2) it would block the message loop (I'm not sure about the real
implication of this, though)


Thanks,
Hajime

Matthias Wabersich wrote:
> 
> Hi Anton,
> 
>> I also se some: D:  [lt-pulseaudio] rtsp_client.c: Sending command:
>> RECORD E: [raop-sink] module-raop-sink.c: Failed to send UDP packet:
>> Resource temporarily unavailable
> 
> I wrote a short patch for this case (see [1]) against Hajime's
> raop2-for-merge branch.
> I found my suspected reason (at least in my case) to hold true. Just
> after connection to the UDP streaming port of my remote device was
> established, I encountered the same issue you described above.
> Using a debugger one could see that the number of bytes written by
> pa_write() in udp_send_audio_packet() was higher than the UDP send
> buffer of my host (as seen in /proc/sys/net/core/wmem_max), which leads
> to pa_write() returning -1 and setting errno to 11 (EAGAIN).
> 
> As the manpage of send(2) states, one should use select(2) to determine
> when the send buffer is free again. I implemented this using pa_poll()
> in raop_client.c.
> 
> It would be great if you could give it a try.
> 
> Greetings,
> 
> Matthias
> 
> [1]: Patch to raop_client.c to support EAGAIN with non-blocking UDP socket
> diff --git a/src/modules/raop/raop_client.c
> b/src/modules/raop/raop_client.c
> index d320ea5..27b29e7 100644
> --- a/src/modules/raop/raop_client.c
> +++ b/src/modules/raop/raop_client.c
> @@ -54,6 +54,7 @@
>  #include <pulsecore/macro.h>
>  #include <pulsecore/memchunk.h>
>  #include <pulsecore/random.h>
> +#include <pulsecore/poll.h>
> 
>  #include "raop_client.h"
>  #include "rtsp_client.h"
> @@ -558,9 +559,21 @@ static void udp_build_retrans_header(uint32_t
> *buffer, size_t size, uint16_t seq
>  static ssize_t udp_send_audio_packet(pa_raop_client *c, pa_bool_t
> retrans, uint8_t *buffer, size_t size) {
>      ssize_t length;
>      int fd = retrans ? c->udp_control_fd : c->udp_stream_fd;
> +    struct pollfd block_fd;
> 
> -    length = pa_write(fd, buffer, size, NULL);
> +    for(;;) {
> +        length = pa_write(fd, buffer, size, NULL);
> 
> +        if ((length < 0) && ((errno == EAGAIN) || (errno ==
> EWOULDBLOCK))  ) {
> +            pa_log_debug("Non-blocking socket blocked, retrying packet
> %d", c->seq);
> +            block_fd.fd = fd;
> +            block_fd.events = POLLOUT;
> +            if (pa_poll(&block_fd, 1, -1) >= 0)
> +                continue;
> +        } else
> +            break;
> +
> +    }
>      return length;
>  }
> 
> _______________________________________________
> pulseaudio-discuss mailing list
> pulseaudio-discuss at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss



More information about the pulseaudio-discuss mailing list