]> err.no Git - varnish/commitdiff
Add Semaphore facility to synchronize different treads in the tester
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 10 Jul 2008 10:26:17 +0000 (10:26 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 10 Jul 2008 10:26:17 +0000 (10:26 +0000)
with each other.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2915 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishtest/Makefile.am
varnish-cache/bin/varnishtest/vtc.c
varnish-cache/bin/varnishtest/vtc.h
varnish-cache/bin/varnishtest/vtc_http.c
varnish-cache/bin/varnishtest/vtc_sema.c [new file with mode: 0644]

index 3a219d0323d03ac5b4ea3a79963c7334abac84a2..3eb45591b2ccdf42bfda6174fb7ea51058c5f404 100644 (file)
@@ -10,6 +10,7 @@ varnishtest_SOURCES = \
                vtc_client.c \
                vtc_http.c \
                vtc_log.c \
+               vtc_sema.c \
                vtc_server.c \
                vtc_varnish.c
 
index 729470eaf2463a7b7bca7b1434ff62937afd35d7..92e7e0c196c71dba1331a6d517777802b0039fa2 100644 (file)
@@ -283,6 +283,7 @@ static struct cmds cmds[] = {
        { "delay",      cmd_delay },
        { "test",       cmd_test },
        { "shell",      cmd_shell },
+       { "sema",       cmd_sema },
        { NULL,         NULL }
 };
 
@@ -328,6 +329,7 @@ main(int argc, char * const *argv)
        }
        argc -= optind;
        argv += optind;
+       init_sema();
        for (ch = 0; ch < argc; ch++)
                exec_file(argv[ch]);
        fok = fopen("_.ok", "w");
index 2233263761f1b6fe62d11878d22949bf48b216dc..5da5cf2b53981affb7c532ba7f26230501e6a55f 100644 (file)
@@ -46,6 +46,9 @@ cmd_f cmd_server;
 cmd_f cmd_client;
 cmd_f cmd_stats;
 cmd_f cmd_varnish;
+cmd_f cmd_sema;
+
+void init_sema(void);
 
 void http_process(struct vtclog *vl, const char *spec, int sock, int client);
 
index 1514738391090d6309a02708d0d9e246d114377d..e96c105ab1eadea082e5d0c54b9e7beb673cae23 100644 (file)
@@ -606,6 +606,7 @@ static struct cmds http_cmds[] = {
        { "send",       cmd_http_send },
        { "chunked",    cmd_http_chunked },
        { "delay",      cmd_delay },
+       { "sema",       cmd_sema },
        { NULL,         NULL }
 };
 
diff --git a/varnish-cache/bin/varnishtest/vtc_sema.c b/varnish-cache/bin/varnishtest/vtc_sema.c
new file mode 100644 (file)
index 0000000..6276ee9
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2006-2008 Linpro AS
+ * All rights reserved.
+ * 
+ * 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.
+ *
+ * $Id: vtc_sema.c 2906 2008-07-08 10:29:07Z phk $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "vtc.h"
+
+#include "vqueue.h"
+#include "miniobj.h"
+#include "libvarnish.h"
+
+struct sema {
+       unsigned                magic;
+#define SEMA_MAGIC             0x29b64317
+       char                    *name;
+       struct vtclog           *vl;
+       VTAILQ_ENTRY(sema)      list;
+       pthread_mutex_t         mtx;
+       pthread_cond_t          cond;
+
+       unsigned                waiters;
+       unsigned                expected;
+};
+
+static pthread_mutex_t         sema_mtx;
+static VTAILQ_HEAD(, sema)     semas = VTAILQ_HEAD_INITIALIZER(semas);
+
+/**********************************************************************
+ * Allocate and initialize a sema
+ */
+
+static struct sema *
+sema_new(char *name)
+{
+       struct sema *r;
+
+       ALLOC_OBJ(r, SEMA_MAGIC);
+       AN(r);
+       r->vl = vtc_logopen(name);
+       AN(r->vl);
+       r->name = name;
+       if (*name != 'r')
+               vtc_log(r->vl, 0, "Sema name must start with 'r'");
+
+       AZ(pthread_mutex_init(&r->mtx, NULL));
+       AZ(pthread_cond_init(&r->cond, NULL));
+       r->waiters = 0;
+       r->expected = 0;
+       VTAILQ_INSERT_TAIL(&semas, r, list);
+       return (r);
+}
+
+/**********************************************************************
+ * Sync a sema
+ */
+
+static void
+sema_sync(struct sema *r, const char *av)
+{
+       unsigned u;
+
+       u = strtoul(av, NULL, 0);
+
+       AZ(pthread_mutex_lock(&r->mtx));
+       if (r->expected == 0)
+               r->expected = u;
+       assert(r->expected == u);
+
+       if (++r->waiters == r->expected) {
+               vtc_log(r->vl, 4, "Wake %u", r->expected);
+               AZ(pthread_cond_broadcast(&r->cond));
+               r->waiters = 0;
+               r->expected = 0;
+       } else 
+               AZ(pthread_cond_wait(&r->cond, &r->mtx));
+       AZ(pthread_mutex_unlock(&r->mtx));
+}
+
+/**********************************************************************
+ * Semaphore command dispatch
+ */
+
+void
+cmd_sema(CMD_ARGS)
+{
+       struct sema *r, *r2;
+
+       (void)priv;
+       (void)cmd;
+
+       if (av == NULL) {
+               AZ(pthread_mutex_lock(&sema_mtx));
+               /* Reset and free */
+               VTAILQ_FOREACH_SAFE(r, &semas, list, r2) {
+                       VTAILQ_REMOVE(&semas, r, list);
+                       FREE_OBJ(r);
+                       /* XXX: MEMLEAK */
+               }
+               AZ(pthread_mutex_unlock(&sema_mtx));
+               return;
+       }
+
+       assert(!strcmp(av[0], "sema"));
+       av++;
+
+       AZ(pthread_mutex_lock(&sema_mtx));
+       VTAILQ_FOREACH(r, &semas, list)
+               if (!strcmp(r->name, av[0]))
+                       break;
+       if (r == NULL) 
+               r = sema_new(av[0]);
+       AZ(pthread_mutex_unlock(&sema_mtx));
+       av++;
+
+       for (; *av != NULL; av++) {
+               if (!strcmp(*av, "sync")) {
+                       av++;
+                       AN(*av);
+                       sema_sync(r, *av);
+                       continue;
+               }
+               vtc_log(r->vl, 0, "Unknown sema argument: %s", *av);
+       }
+}
+
+void
+init_sema(void)
+{
+       AZ(pthread_mutex_init(&sema_mtx, NULL));
+}