vinyl-cache/bin/vinyld/waiter/cache_waiter.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 */
31
32
#include "config.h"
33
34
#include "cache/cache_int.h"
35
36
#include <stdlib.h>
37
38
#include "vbh.h"
39
40
#include "waiter/waiter.h"
41
#include "waiter/waiter_priv.h"
42
#include "waiter/mgt_waiter.h"
43
44
#include "VSC_waiter.h"
45
46
static int v_matchproto_(vbh_cmp_t)
47 801
waited_cmp(void *priv, const void *a, const void *b)
48
{
49
        const struct waiter *ww;
50
        const struct waited *aa, *bb;
51
52 801
        CAST_OBJ_NOTNULL(ww, priv, WAITER_MAGIC);
53 801
        CAST_OBJ_NOTNULL(aa, a, WAITED_MAGIC);
54 801
        CAST_OBJ_NOTNULL(bb, b, WAITED_MAGIC);
55
56 801
        return (Wait_When(aa) < Wait_When(bb));
57
}
58
59
static void v_matchproto_(vbh_update_t)
60 17236
waited_update(void *priv, void *p, unsigned u)
61
{
62
        struct waited *pp;
63
64 17236
        (void)priv;
65 17236
        CAST_OBJ_NOTNULL(pp, p, WAITED_MAGIC);
66 17236
        pp->idx = u;
67 17236
}
68
69
/**********************************************************************/
70
71
void
72 7972
Wait_Call(const struct waiter *w, struct waited *wp,
73
    enum wait_event ev, double now)
74
{
75 7972
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
76 7972
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
77 7972
        AN(wp->func);
78 7972
        assert(wp->idx == VBH_NOIDX);
79 7972
        AN(w->vsc);
80
81 7972
        switch (ev) {
82
        case WAITER_REMCLOSE:
83 4102
                w->vsc->remclose++;
84 4102
                break;
85
        case WAITER_TIMEOUT:
86 52
                w->vsc->timeout++;
87 52
                break;
88
        case WAITER_ACTION:
89 3818
                w->vsc->action++;
90 3818
                break;
91
        default:
92 0
                break;
93
        }
94
95 7972
        wp->func(wp, ev, now);
96 7972
}
97
98
/**********************************************************************/
99
100
void
101 8096
Wait_HeapInsert(const struct waiter *w, struct waited *wp)
102
{
103 8096
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
104 8096
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
105 8096
        assert(wp->idx == VBH_NOIDX);
106 8096
        AN(w->vsc);
107 8096
        w->vsc->conns++;
108 8096
        VBH_insert(w->heap, wp);
109 8096
}
110
111
/*
112
 * XXX: wp is const because otherwise FlexeLint complains.  However, *wp
113
 * XXX: will actually change as a result of calling this function, via
114
 * XXX: the pointer stored in the bin-heap.  I can see how this const
115
 * XXX: could maybe confuse a compilers optimizer, but I do not expect
116
 * XXX: any harm to come from it.  Caveat Emptor.
117
 */
118
119
int
120 7971
Wait_HeapDelete(const struct waiter *w, const struct waited *wp)
121
{
122 7971
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
123 7971
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
124 7971
        if (wp->idx == VBH_NOIDX)
125 0
                return (0);
126 7971
        AN(w->vsc);
127 7971
        w->vsc->conns--;
128 7971
        VBH_delete(w->heap, wp->idx);
129 7971
        return (1);
130 7971
}
131
132
double
133 20390
Wait_HeapDue(const struct waiter *w, struct waited **wpp)
134
{
135
        struct waited *wp;
136
137 20390
        wp = VBH_root(w->heap);
138 20390
        CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
139 20390
        if (wp == NULL) {
140 15418
                if (wpp != NULL)
141 15418
                        *wpp = NULL;
142 15418
                return (0);
143
        }
144 4972
        if (wpp != NULL)
145 4740
                *wpp = wp;
146 4972
        return (Wait_When(wp));
147 20390
}
148
149
/**********************************************************************/
150
151
int
152 8095
Wait_Enter(const struct waiter *w, struct waited *wp)
153
{
154
155 8095
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
156 8095
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
157 8095
        assert(wp->fd > 0);                     // stdin never comes here
158 8095
        AN(wp->func);
159 8095
        wp->idx = VBH_NOIDX;
160 8095
        return (w->impl->enter(w->priv, wp));
161
}
162
163
/**********************************************************************/
164
165
const char *
166 44
Waiter_GetName(void)
167
{
168
169 44
        if (waiter != NULL)
170 44
                return (waiter->name);
171
        else
172 0
                return ("(No Waiter?)");
173 44
}
174
175
struct waiter *
176 7696
Waiter_New(const char *name)
177
{
178
        struct waiter *w;
179
180 7696
        AN(waiter);
181 7696
        AN(waiter->name);
182 7696
        AN(waiter->init);
183 7696
        AN(waiter->enter);
184 7696
        AN(waiter->fini);
185
186 7696
        w = calloc(1, sizeof (struct waiter) + waiter->size);
187 7696
        AN(w);
188 7696
        INIT_OBJ(w, WAITER_MAGIC);
189 7696
        w->priv = (void*)(w + 1);
190 7696
        w->impl = waiter;
191 7696
        VTAILQ_INIT(&w->waithead);
192 7696
        w->heap = VBH_new(w, waited_cmp, waited_update);
193
194 7696
        AZ(w->vsc);
195 7696
        w->vsc = VSC_waiter_New(NULL, NULL, "%s", name);
196 7696
        AN(w->vsc);
197
198 7696
        waiter->init(w);
199
200 7696
        return (w);
201
}
202
203
void
204 8
Waiter_Destroy(struct waiter **wp)
205
{
206
        struct waiter *w;
207
208 8
        TAKE_OBJ_NOTNULL(w, wp, WAITER_MAGIC);
209
210 8
        AZ(VBH_root(w->heap));
211 8
        AN(w->impl->fini);
212 8
        w->impl->fini(w);
213 8
        FREE_OBJ(w);
214 8
}