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