para_recv: handle EAGAIN on non-blocking socket
authorGerrit Renker <grenker@cscs.ch>
Thu, 25 Mar 2010 16:43:22 +0000 (17:43 +0100)
committerAndre Noll <maan@systemlinux.org>
Thu, 25 Mar 2010 16:43:22 +0000 (17:43 +0100)
Checking whether the non-blocking socket is readable is not sufficient
to guarantee that EAGAIN is not encountered on the non-blocking socket,
the following was observed in the middle of a UDP/FEC stream:

Mar 24 17:12:44:0533 audi (0) decode_group: writing group 2784 (4232/4374 decoded data bytes)
Mar 24 17:12:44:0710 audi (0) get_time_string: slot 0: 32:42 [94:49] (26%/127:31)
Mar 24 17:12:44:0710 audi (2) btr_remove_node: removing btr node udp from buffer tree
Mar 24 17:12:44:0710 audi (1) unregister_task: unregistering udp receiver node (Resource temporarily unavailable)

The patch fixes the problem by not interpreting the case "data not
yet ready" as an error, but as a temporary condition.

dccp_recv.c
udp_recv.c

index c22fa84..883451c 100644 (file)
@@ -166,6 +166,9 @@ static void dccp_recv_post_select(struct sched *s, struct task *t)
        if (iovcnt == 0)
                goto err;
        ret = para_readv(pdd->fd, iov, iovcnt);
+       /* EAGAIN is possible even if FD_ISSET */
+       if (ret < 0 && is_errno(-ret, EAGAIN))
+               return;
        if (ret == 0)
                ret = -E_RECV_EOF;
        if (ret < 0)
index 4f363cc..316957d 100644 (file)
@@ -92,6 +92,9 @@ static void udp_recv_post_select(__a_unused struct sched *s, struct task *t)
        if (iovcnt == 0)
                goto err;
        ret = para_readv(purd->fd, iov, iovcnt);
+       /* EAGAIN is possible even if FD_ISSET */
+       if (ret < 0 && is_errno(-ret, EAGAIN))
+               return;
        if (ret == 0)
                ret = -E_RECV_EOF;
        if (ret < 0)