[master] c9e3914 Abstract some "manage list of backends" code which most of the directors will need.
Poul-Henning Kamp
phk at varnish-cache.org
Mon Mar 11 12:07:05 CET 2013
commit c9e3914a79bf3f787b735e365085a348a8be60b2
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Mar 11 11:06:34 2013 +0000
Abstract some "manage list of backends" code which most of the directors
will need.
diff --git a/lib/libvmod_directors/Makefile.am b/lib/libvmod_directors/Makefile.am
index bc230a5..341c223 100644
--- a/lib/libvmod_directors/Makefile.am
+++ b/lib/libvmod_directors/Makefile.am
@@ -14,6 +14,7 @@ noinst_LTLIBRARIES = libvmod_directors.la
libvmod_directors_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -shared -rpath /nowhere
libvmod_directors_la_SOURCES = \
+ vdir.c \
round_robin.c
nodist_libvmod_directors_la_SOURCES = \
diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c
index 9339046..240bcb7 100644
--- a/lib/libvmod_directors/round_robin.c
+++ b/lib/libvmod_directors/round_robin.c
@@ -36,61 +36,45 @@
#include "vrt.h"
#include "vcc_if.h"
-struct rr_entry {
- unsigned magic;
-#define RR_ENTRY_MAGIC 0xa80970cf
- VTAILQ_ENTRY(rr_entry) list;
- VCL_BACKEND be;
-};
+#include "vdir.h"
struct vmod_directors_round_robin {
unsigned magic;
-#define VMOD_DEBUG_RR_MAGIC 0x99f4b726
- VTAILQ_HEAD(, rr_entry) listhead;
- int nbe;
- pthread_mutex_t mtx;
- struct director *dir;
+#define VMOD_DIRECTORS_ROUND_ROBIN_MAGIC 0xa80970cf
+ struct vdir *vd;
+ unsigned nxt;
};
-static unsigned
+static unsigned __match_proto__(vdi_healthy)
vmod_rr_healthy(const struct director *dir, const struct req *req)
{
- struct rr_entry *ep;
struct vmod_directors_round_robin *rr;
- unsigned retval = 0;
- CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DEBUG_RR_MAGIC);
- AZ(pthread_mutex_lock(&rr->mtx));
- VTAILQ_FOREACH(ep, &rr->listhead, list) {
- if (ep->be->healthy(ep->be, req)) {
- retval = 1;
- break;
- }
- }
- AZ(pthread_mutex_unlock(&rr->mtx));
- return (retval);
+ CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
+ return (vdir_any_healthy(rr->vd, req));
}
-static struct vbc *
+static struct vbc * __match_proto__(vdi_getfd_f)
vmod_rr_getfd(const struct director *dir, struct req *req)
{
- struct rr_entry *ep = NULL;
struct vmod_directors_round_robin *rr;
- int i;
-
- CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DEBUG_RR_MAGIC);
- AZ(pthread_mutex_lock(&rr->mtx));
- for (i = 0; i < rr->nbe; i++) {
- ep = VTAILQ_FIRST(&rr->listhead);
- VTAILQ_REMOVE(&rr->listhead, ep, list);
- VTAILQ_INSERT_TAIL(&rr->listhead, ep, list);
- if (ep->be->healthy(ep->be, req))
+ unsigned u;
+ VCL_BACKEND be = NULL;
+
+ CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
+ vdir_lock(rr->vd);
+ for (u = 0; u < rr->vd->n_backend; u++) {
+ rr->nxt %= rr->vd->n_backend;
+ be = rr->vd->backend[rr->nxt];
+ rr->nxt++;
+ CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
+ if (be->healthy(be, req))
break;
}
- AZ(pthread_mutex_unlock(&rr->mtx));
- if (i == rr->nbe || ep == NULL)
+ vdir_unlock(rr->vd);
+ if (u == rr->vd->n_backend || be == NULL)
return (NULL);
- return (ep->be->getfd(ep->be, req));
+ return (be->getfd(be, req));
}
VCL_VOID
@@ -99,65 +83,42 @@ vmod_round_robin__init(struct req *req, struct vmod_directors_round_robin **rrp,
{
struct vmod_directors_round_robin *rr;
- (void)req;
-
+ AZ(req);
AN(rrp);
AZ(*rrp);
- ALLOC_OBJ(rr, VMOD_DEBUG_RR_MAGIC);
+ ALLOC_OBJ(rr, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
AN(rr);
*rrp = rr;
- AZ(pthread_mutex_init(&rr->mtx, NULL));
- VTAILQ_INIT(&rr->listhead);
- ALLOC_OBJ(rr->dir, DIRECTOR_MAGIC);
- AN(rr->dir);
- REPLACE(rr->dir->vcl_name, vcl_name);
- rr->dir->priv = rr;
- rr->dir->healthy = vmod_rr_healthy;
- rr->dir->getfd = vmod_rr_getfd;
+ vdir_new(&rr->vd, vcl_name, vmod_rr_healthy, vmod_rr_getfd, rr);
}
VCL_VOID
vmod_round_robin__fini(struct req *req, struct vmod_directors_round_robin **rrp)
{
struct vmod_directors_round_robin *rr;
- struct rr_entry *ep;
-
- (void)req;
+ AZ(req);
rr = *rrp;
*rrp = NULL;
- CHECK_OBJ_NOTNULL(rr, VMOD_DEBUG_RR_MAGIC);
-
- AZ(pthread_mutex_destroy(&rr->mtx));
- while (!VTAILQ_EMPTY(&rr->listhead)) {
- ep = VTAILQ_FIRST(&rr->listhead);
- VTAILQ_REMOVE(&rr->listhead, ep, list);
- FREE_OBJ(ep);
- }
- free(rr->dir->vcl_name);
- FREE_OBJ(rr->dir);
+ CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
+ vdir_delete(&rr->vd);
FREE_OBJ(rr);
}
VCL_VOID
-vmod_round_robin_add_backend(struct req *req, struct vmod_directors_round_robin * rr,
- VCL_BACKEND be)
+vmod_round_robin_add_backend(struct req *req,
+ struct vmod_directors_round_robin *rr, VCL_BACKEND be)
{
- struct rr_entry *ep;
- (void)req;
- ALLOC_OBJ(ep, RR_ENTRY_MAGIC);
- AN(ep);
- ep->be = be;
- AZ(pthread_mutex_lock(&rr->mtx));
- VTAILQ_INSERT_TAIL(&rr->listhead, ep, list);
- rr->nbe++;
- AZ(pthread_mutex_unlock(&rr->mtx));
+ (void)req;
+ CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
+ vdir_add_backend(rr->vd, be, 0.0);
}
VCL_BACKEND __match_proto__()
vmod_round_robin_backend(struct req *req, struct vmod_directors_round_robin *rr)
{
(void)req;
- return (rr->dir);
+ CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
+ return (rr->vd->dir);
}
diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c
new file mode 100644
index 0000000..be8f340
--- /dev/null
+++ b/lib/libvmod_directors/vdir.c
@@ -0,0 +1,144 @@
+/*-
+ * Copyright (c) 2013 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "cache/cache.h"
+#include "cache/cache_backend.h"
+
+#include "vrt.h"
+
+#include "vdir.h"
+
+static void
+vdir_expand(struct vdir *vd, unsigned n)
+{
+ CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
+
+ vd->backend = realloc(vd->backend, n * sizeof *vd->backend);
+ AN(vd->backend);
+ vd->weight = realloc(vd->weight, n * sizeof *vd->weight);
+ AN(vd->weight);
+ vd->l_backend = n;
+}
+
+void
+vdir_new(struct vdir **vdp, const char *vcl_name, vdi_healthy *healthy,
+ vdi_getfd_f *getfd, void *priv)
+{
+ struct vdir *vd;
+
+ AN(vcl_name);
+ AN(vdp);
+ AZ(*vdp);
+ ALLOC_OBJ(vd, VDIR_MAGIC);
+ AN(vd);
+ *vdp = vd;
+ AZ(pthread_mutex_init(&vd->mtx, NULL));
+
+ ALLOC_OBJ(vd->dir, DIRECTOR_MAGIC);
+ AN(vd->dir);
+ REPLACE(vd->dir->vcl_name, vcl_name);
+ vd->dir->priv = priv;
+ vd->dir->healthy = healthy;
+ vd->dir->getfd = getfd;
+}
+
+void
+vdir_delete(struct vdir **vdp)
+{
+ struct vdir *vd;
+
+ AN(vdp);
+ vd = *vdp;
+ *vdp = NULL;
+
+ CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
+
+ free(vd->backend);
+ free(vd->weight);
+ AZ(pthread_mutex_destroy(&vd->mtx));
+ FREE_OBJ(vd->dir);
+ FREE_OBJ(vd);
+}
+
+void
+vdir_lock(struct vdir *vd)
+{
+ CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
+ AZ(pthread_mutex_lock(&vd->mtx));
+}
+
+void
+vdir_unlock(struct vdir *vd)
+{
+ CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
+ AZ(pthread_mutex_unlock(&vd->mtx));
+}
+
+
+unsigned
+vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight)
+{
+ unsigned u;
+
+ CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
+ AN(be);
+ vdir_lock(vd);
+ if (vd->n_backend >= vd->l_backend)
+ vdir_expand(vd, vd->l_backend + 16);
+ assert(vd->n_backend < vd->l_backend);
+ u = vd->n_backend++;
+ vd->backend[u] = be;
+ vd->weight[u] = weight;
+ vdir_unlock(vd);
+ return (u);
+}
+
+unsigned
+vdir_any_healthy(struct vdir *vd, const struct req *req)
+{
+ unsigned retval = 0;
+ VCL_BACKEND be;
+ unsigned u;
+
+ CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
+ vdir_lock(vd);
+ for (u = 0; u < vd->n_backend; u++) {
+ be = vd->backend[u];
+ CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
+ if (be->healthy(be, req)) {
+ retval = 1;
+ break;
+ }
+ }
+ vdir_unlock(vd);
+ return (retval);
+}
diff --git a/lib/libvmod_directors/vdir.h b/lib/libvmod_directors/vdir.h
new file mode 100644
index 0000000..1b588b4
--- /dev/null
+++ b/lib/libvmod_directors/vdir.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2013 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+struct vdir {
+ unsigned magic;
+#define VDIR_MAGIC 0x99f4b726
+ pthread_mutex_t mtx;
+ unsigned n_backend;
+ unsigned l_backend;
+ VCL_BACKEND *backend;
+ double *weight;
+ struct director *dir;
+};
+
+void vdir_new(struct vdir **vdp, const char *vcl_name, vdi_healthy *healthy,
+ vdi_getfd_f *getfd, void *priv);
+void vdir_delete(struct vdir **vdp);
+void vdir_lock(struct vdir *vd);
+void vdir_unlock(struct vdir *vd);
+unsigned vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight);
+unsigned vdir_any_healthy(struct vdir *vd, const struct req *);
More information about the varnish-commit
mailing list