udp: Remove chunk queueing.
authorAndre Noll <maan@systemlinux.org>
Wed, 6 Oct 2010 22:08:31 +0000 (00:08 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 31 Oct 2010 11:18:24 +0000 (12:18 +0100)
This was broken beyond repair for several reasons:

First of all, not each write to a UDP socket with no listener on
the remote leads to a write error. For a local connection on Linux,
only each second write yields ECONNREFUSED while all others seem to
succeed. So we would only queue each second FEC slice which is next
to useless.

Secondly, only buffer references are stored in the chunk queue, the
buffer contents are not copied for performance reasons. This works fine
if the buffers point to the read-only memory map of the audio file,
which is the case for the HTTP sender, but not for the UDP sender.
In fact, for UDP the buffer is always the same, namely ->enc_buf of
the FEC client struct for the UDP target.

Finally, it is not clear that the buffer references stored in the chunk
queue are still valid when the chunk queue is emptied by sending the
buffers since vss.c might have realloced the enc_buf.

So remove that broken code and be happy.

udp_send.c

index 9092985725b5289ee7391eba3df2c12ae4e62844..f39b4f1435d1189308637c306a5be13e4cf855a1 100644 (file)
@@ -30,7 +30,6 @@
 #include "fd.h"
 #include "sched.h"
 #include "close_on_fork.h"
-#include "chunk_queue.h"
 
 /**
  * Time window during which ICMP Destination/Port Unreachable messages are
@@ -57,12 +56,8 @@ static void udp_close_target(struct sender_client *sc)
        const char *buf;
        size_t len = vss_get_fec_eof_packet(&buf);
 
-       if (sc->cq != NULL) {
-               /* ignore return value, closing the target anyway. */
-               (void)write(sc->fd, buf, len);
-               cq_destroy(sc->cq);
-               sc->cq = NULL;
-       }
+       /* ignore return value, closing the target anyway. */
+       (void)write(sc->fd, buf, len);
 }
 
 static void udp_delete_target(struct sender_client *sc, const char *msg)
@@ -156,15 +151,9 @@ err:
        return -ERRNO_TO_PARA_ERROR(errno);
 }
 
-/** The maximal size of the per-target chunk queue. */
-#define UDP_CQ_BYTES 40000
-
 static void udp_init_session(struct sender_client *sc)
 {
-       if (sc->cq == NULL) {
-               sc->cq = cq_new(UDP_CQ_BYTES);
-               PARA_NOTICE_LOG("sending to udp %s\n", sc->name);
-       }
+       PARA_NOTICE_LOG("sending to udp %s\n", sc->name);
 }
 
 static void udp_shutdown_targets(void)
@@ -290,19 +279,11 @@ static int udp_send_fec(struct sender_client *sc, char *buf, size_t len)
 
        if (sender_status == SENDER_OFF)
                return 0;
-       if (len == 0 && !cq_peek(sc->cq))
+       if (len == 0)
                return 0;
        ret = udp_check_socket_state(sc);
        if (ret < 0)
                goto fail;
-       ret = send_queued_chunks(sc->fd, sc->cq);
-       if (ret < 0)
-               goto fail;
-       if (!ret) { /* still data left in the queue */
-               ret = cq_force_enqueue(sc->cq, buf, len);
-               assert(ret >= 0);
-               return 0;
-       }
        ret = write_nonblock(sc->fd, buf, len);
        if (ret == -ERRNO_TO_PARA_ERROR(ECONNREFUSED)) {
                /*
@@ -313,10 +294,6 @@ static int udp_send_fec(struct sender_client *sc, char *buf, size_t len)
        }
        if (ret < 0)
                goto fail;
-       if (ret != len) {
-               ret = cq_force_enqueue(sc->cq, buf + ret, len - ret);
-               assert(ret >= 0);
-       }
        return 1;
 fail:
        udp_delete_target(sc, para_strerror(-ret));