varnish-cache/bin/varnishd/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_varnishd.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
static int v_matchproto_(vbh_cmp_t)
45 5133
waited_cmp(void *priv, const void *a, const void *b)
46
{
47
        const struct waiter *ww;
48
        const struct waited *aa, *bb;
49
50 5133
        CAST_OBJ_NOTNULL(ww, priv, WAITER_MAGIC);
51 5133
        CAST_OBJ_NOTNULL(aa, a, WAITED_MAGIC);
52 5133
        CAST_OBJ_NOTNULL(bb, b, WAITED_MAGIC);
53
54 5133
        return (Wait_When(aa) < Wait_When(bb));
55
}
56
57
static void v_matchproto_(vbh_update_t)
58 99393
waited_update(void *priv, void *p, unsigned u)
59
{
60
        struct waited *pp;
61
62 99393
        (void)priv;
63 99393
        CAST_OBJ_NOTNULL(pp, p, WAITED_MAGIC);
64 99393
        pp->idx = u;
65 99393
}
66
67
/**********************************************************************/
68
69
void
70 45783
Wait_Call(const struct waiter *w, struct waited *wp,
71
    enum wait_event ev, double now)
72
{
73 45783
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
74 45783
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
75 45783
        AN(wp->func);
76 45783
        assert(wp->idx == VBH_NOIDX);
77 45783
        wp->func(wp, ev, now);
78 45783
}
79
80
/**********************************************************************/
81
82
void
83 46330
Wait_HeapInsert(const struct waiter *w, struct waited *wp)
84
{
85 46330
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
86 46330
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
87 46330
        assert(wp->idx == VBH_NOIDX);
88 46330
        VBH_insert(w->heap, wp);
89 46330
}
90
91
/*
92
 * XXX: wp is const because otherwise FlexeLint complains.  However, *wp
93
 * XXX: will actually change as a result of calling this function, via
94
 * XXX: the pointer stored in the bin-heap.  I can see how this const
95
 * XXX: could maybe confuse a compilers optimizer, but I do not expect
96
 * XXX: any harm to come from it.  Caveat Emptor.
97
 */
98
99
int
100 45782
Wait_HeapDelete(const struct waiter *w, const struct waited *wp)
101
{
102 45782
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
103 45782
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
104 45782
        if (wp->idx == VBH_NOIDX)
105 0
                return (0);
106 45782
        VBH_delete(w->heap, wp->idx);
107 45782
        return (1);
108 45782
}
109
110
double
111 117650
Wait_HeapDue(const struct waiter *w, struct waited **wpp)
112
{
113
        struct waited *wp;
114
115 117650
        wp = VBH_root(w->heap);
116 117650
        CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
117 117650
        if (wp == NULL) {
118 88768
                if (wpp != NULL)
119 88768
                        *wpp = NULL;
120 88768
                return (0);
121
        }
122 28882
        if (wpp != NULL)
123 27056
                *wpp = wp;
124 28882
        return (Wait_When(wp));
125 117650
}
126
127
/**********************************************************************/
128
129
int
130 46328
Wait_Enter(const struct waiter *w, struct waited *wp)
131
{
132
133 46328
        CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
134 46328
        CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
135 46328
        assert(wp->fd > 0);                     // stdin never comes here
136 46328
        AN(wp->func);
137 46328
        wp->idx = VBH_NOIDX;
138 46328
        return (w->impl->enter(w->priv, wp));
139
}
140
141
/**********************************************************************/
142
143
const char *
144 297
Waiter_GetName(void)
145
{
146
147 297
        if (waiter != NULL)
148 297
                return (waiter->name);
149
        else
150 0
                return ("(No Waiter?)");
151 297
}
152
153
struct waiter *
154 43944
Waiter_New(void)
155
{
156
        struct waiter *w;
157
158 43944
        AN(waiter);
159 43944
        AN(waiter->name);
160 43944
        AN(waiter->init);
161 43944
        AN(waiter->enter);
162 43944
        AN(waiter->fini);
163
164 43944
        w = calloc(1, sizeof (struct waiter) + waiter->size);
165 43944
        AN(w);
166 43944
        INIT_OBJ(w, WAITER_MAGIC);
167 43944
        w->priv = (void*)(w + 1);
168 43944
        w->impl = waiter;
169 43944
        VTAILQ_INIT(&w->waithead);
170 43944
        w->heap = VBH_new(w, waited_cmp, waited_update);
171
172 43944
        waiter->init(w);
173
174 43944
        return (w);
175
}
176
177
void
178 50
Waiter_Destroy(struct waiter **wp)
179
{
180
        struct waiter *w;
181
182 50
        TAKE_OBJ_NOTNULL(w, wp, WAITER_MAGIC);
183
184 50
        AZ(VBH_root(w->heap));
185 50
        AN(w->impl->fini);
186 50
        w->impl->fini(w);
187 50
        FREE_OBJ(w);
188 50
}