http_recv: Fill both buffer pool buffers simultaneously.
authorAndre Noll <maan@systemlinux.org>
Tue, 20 Sep 2011 22:55:05 +0000 (00:55 +0200)
committerAndre Noll <maan@systemlinux.org>
Tue, 1 Nov 2011 11:44:59 +0000 (12:44 +0100)
This changes http_recv_post_select() to call readv_nonblock() rather
than read_nonblock() to read data from the socket, just like the udp
and dccp receivers do.

This saves one iteration of the scheduler loop if the end of the
buffer pool area is reached.

http_recv.c

index d4fe29a..e6031e7 100644 (file)
@@ -79,14 +79,14 @@ static void http_recv_post_select(struct sched *s, struct task *t)
        struct receiver_node *rn = container_of(t, struct receiver_node, task);
        struct private_http_recv_data *phd = rn->private_data;
        struct btr_node *btrn = rn->btrn;
-       int ret;
-       char *buf;
-       size_t sz, n;
+       int ret, iovcnt;
+       struct iovec iov[2];
+       size_t num_bytes;
 
        t->error = 0;
        ret = btr_node_status(btrn, 0, BTR_NT_ROOT);
        if (ret < 0)
-               goto err;
+               goto out;
        if (ret == 0)
                return;
        if (phd->status == HTTP_CONNECTED) {
@@ -98,14 +98,14 @@ static void http_recv_post_select(struct sched *s, struct task *t)
                ret = send_va_buffer(rn->fd, "%s", rq);
                free(rq);
                if (ret < 0)
-                       goto err;
+                       goto out;
                phd->status = HTTP_SENT_GET_REQUEST;
                return;
        }
        if (phd->status == HTTP_SENT_GET_REQUEST) {
                ret = read_pattern(rn->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG), &s->rfds);
                if (ret < 0)
-                       goto err;
+                       goto out;
                if (ret == 0)
                        return;
                PARA_INFO_LOG("received ok msg, streaming\n");
@@ -113,15 +113,21 @@ static void http_recv_post_select(struct sched *s, struct task *t)
                return;
        }
        ret = -E_HTTP_RECV_OVERRUN;
-       sz = btr_pool_get_buffer(rn->btrp, &buf);
-       if (sz == 0)
-               goto err;
-       ret = read_nonblock(rn->fd, buf, sz, &s->rfds, &n);
-       if (n > 0)
-               btr_add_output_pool(rn->btrp, n, btrn);
+       iovcnt = btr_pool_get_buffers(rn->btrp, iov);
+       if (iovcnt == 0)
+               goto out;
+       ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes);
+       if (num_bytes == 0)
+               goto out;
+       if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */
+               btr_add_output_pool(rn->btrp, num_bytes, btrn);
+       else { /* both buffers contain data */
+               btr_add_output_pool(rn->btrp, iov[0].iov_len, btrn);
+               btr_add_output_pool(rn->btrp, num_bytes - iov[0].iov_len, btrn);
+       }
+out:
        if (ret >= 0)
                return;
-err:
        btr_remove_node(rn->btrn);
        t->error = ret;
 }