varnish-cache/bin/varnishd/http1/cache_http1_pipe.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2011 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 * XXX: charge bytes to srcaddr
30
 */
31
32
#include "config.h"
33
34
#include "cache/cache_varnishd.h"
35
36
#include <poll.h>
37
#include <stdio.h>
38
39
#include "cache_http1.h"
40
41
#include "VSC_vbe.h"
42
43
static struct lock pipestat_mtx;
44
45
static int
46 354
rdf(int fd0, int fd1, uint64_t *pcnt)
47
{
48
        int i, j;
49
        char buf[BUFSIZ], *p;
50
51 354
        i = read(fd0, buf, sizeof buf);
52 354
        if (i <= 0)
53 224
                return (1);
54 260
        for (p = buf; i > 0; i -= j, p += j) {
55 130
                j = write(fd1, p, i);
56 130
                if (j <= 0)
57 0
                        return (1);
58 130
                *pcnt += j;
59 130
                if (i != j)
60 0
                        (void)usleep(100000);           /* XXX hack */
61 130
        }
62 130
        return (0);
63 354
}
64
65
int
66 128
V1P_Enter(void)
67
{
68 128
        int retval = 0;
69
70 128
        Lck_Lock(&pipestat_mtx);
71 128
        if (cache_param->pipe_sess_max == 0 ||
72 8
            VSC_C_main->n_pipe < cache_param->pipe_sess_max)
73 120
                VSC_C_main->n_pipe++;
74
        else
75 8
                retval = -1;
76 128
        Lck_Unlock(&pipestat_mtx);
77 128
        return (retval);
78
}
79
80
void
81 120
V1P_Leave(void)
82
{
83
84 120
        Lck_Lock(&pipestat_mtx);
85 120
        assert(VSC_C_main->n_pipe > 0);
86 120
        VSC_C_main->n_pipe--;
87 120
        Lck_Unlock(&pipestat_mtx);
88 120
}
89
90
void
91 120
V1P_Charge(struct req *req, const struct v1p_acct *a, struct VSC_vbe *b)
92
{
93
94 120
        AN(b);
95 240
        VSLb(req->vsl, SLT_PipeAcct, "%ju %ju %ju %ju",
96 120
            (uintmax_t)a->req,
97 120
            (uintmax_t)a->bereq,
98 120
            (uintmax_t)a->in,
99 120
            (uintmax_t)a->out);
100
101 120
        Lck_Lock(&pipestat_mtx);
102 120
        VSC_C_main->s_pipe_hdrbytes += a->req;
103 120
        VSC_C_main->s_pipe_in += a->in;
104 120
        VSC_C_main->s_pipe_out += a->out;
105 120
        b->pipe_hdrbytes += a->bereq;
106 120
        b->pipe_out += a->in;
107 120
        b->pipe_in += a->out;
108 120
        Lck_Unlock(&pipestat_mtx);
109 120
}
110
111
void
112 112
V1P_Process(const struct req *req, int fd, struct v1p_acct *v1a)
113
{
114
        struct pollfd fds[2];
115
        int i, j;
116
117 112
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
118 112
        CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC);
119 112
        assert(fd > 0);
120
121 112
        if (req->htc->pipeline_b != NULL) {
122 46
                j = write(fd,  req->htc->pipeline_b,
123 23
                    req->htc->pipeline_e - req->htc->pipeline_b);
124 23
                if (j < 0)
125 0
                        return;
126 23
                req->htc->pipeline_b = NULL;
127 23
                req->htc->pipeline_e = NULL;
128 23
                v1a->in += j;
129 23
        }
130 112
        memset(fds, 0, sizeof fds);
131 112
        fds[0].fd = fd;
132 112
        fds[0].events = POLLIN;
133 112
        fds[1].fd = req->sp->fd;
134 112
        fds[1].events = POLLIN;
135
136 353
        while (fds[0].fd > -1 || fds[1].fd > -1) {
137 353
                fds[0].revents = 0;
138 353
                fds[1].revents = 0;
139 706
                i = poll(fds, 2,
140 353
                    (int)(cache_param->pipe_timeout * 1e3));
141 353
                if (i < 1)
142 0
                        break;
143 353
                if (fds[0].revents &&
144 232
                    rdf(fd, req->sp->fd, &v1a->out)) {
145 112
                        if (fds[1].fd == -1)
146 8
                                break;
147 104
                        (void)shutdown(fd, SHUT_RD);
148 104
                        (void)shutdown(req->sp->fd, SHUT_WR);
149 104
                        fds[0].events = 0;
150 104
                        fds[0].fd = -1;
151 104
                }
152 345
                if (fds[1].revents &&
153 122
                    rdf(req->sp->fd, fd, &v1a->in)) {
154 112
                        if (fds[0].fd == -1)
155 104
                                break;
156 8
                        (void)shutdown(req->sp->fd, SHUT_RD);
157 8
                        (void)shutdown(fd, SHUT_WR);
158 8
                        fds[1].events = 0;
159 8
                        fds[1].fd = -1;
160 8
                }
161
        }
162 112
}
163
164
/*--------------------------------------------------------------------*/
165
166
void
167 5824
V1P_Init(void)
168
{
169
170 5824
        Lck_New(&pipestat_mtx, lck_pipestat);
171 5824
}