r3514 - trunk/varnish-cache/bin/varnishd
phk at projects.linpro.no
phk at projects.linpro.no
Sun Jan 18 15:26:32 CET 2009
Author: phk
Date: 2009-01-18 15:26:32 +0100 (Sun, 18 Jan 2009)
New Revision: 3514
Modified:
trunk/varnish-cache/bin/varnishd/cache_ban.c
Log:
redo the purge.list function with proper locking
Modified: trunk/varnish-cache/bin/varnishd/cache_ban.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_ban.c 2009-01-14 20:40:54 UTC (rev 3513)
+++ trunk/varnish-cache/bin/varnishd/cache_ban.c 2009-01-18 14:26:32 UTC (rev 3514)
@@ -499,27 +499,30 @@
static void
ccf_purge_list(struct cli *cli, const char * const *av, void *priv)
{
- struct ban *b0;
+ struct ban *b;
struct ban_test *bt;
(void)av;
(void)priv;
- /*
- * XXX: Strictly speaking, this loop traversal is not lock-safe
- * XXX: because we might inspect the last ban while it gets
- * XXX: destroyed. To properly fix this, we would need to either
- * XXX: hold the lock over the entire loop, or grab refcounts
- * XXX: under lock for each element of the list.
- * XXX: We do neither, and hope for the best.
- */
- for (b0 = ban_start; b0 != NULL; b0 = VTAILQ_NEXT(b0, list)) {
- if (b0->refcount == 0 && VTAILQ_NEXT(b0, list) == NULL)
- break;
- VTAILQ_FOREACH(bt, &b0->tests, list)
- cli_out(cli, "%5u %d \"%s\"\n",
- b0->refcount, b0->flags,
- bt->test);
+
+ Lck_Lock(&ban_mtx);
+ VTAILQ_LAST(&ban_head, banhead)->refcount++;
+ Lck_Unlock(&ban_mtx);
+
+ VTAILQ_FOREACH(b, &ban_head, list) {
+ bt = VTAILQ_FIRST(&b->tests);
+ cli_out(cli, "%5u %4s\t%s\n",
+ b->refcount, b->flags ? "Gone" : "", bt->test);
+ do {
+ bt = VTAILQ_NEXT(bt, list);
+ if (bt != NULL)
+ cli_out(cli, "\t\t%s\n", bt->test);
+ } while (bt != NULL);
}
+
+ Lck_Lock(&ban_mtx);
+ VTAILQ_LAST(&ban_head, banhead)->refcount--;
+ Lck_Unlock(&ban_mtx);
}
static struct cli_proto ban_cmds[] = {
More information about the varnish-commit
mailing list