Commit fd499846 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

redo the purge.list function with proper locking



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3514 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent f50a3412
...@@ -499,27 +499,30 @@ ccf_purge_hash(struct cli *cli, const char * const *av, void *priv) ...@@ -499,27 +499,30 @@ ccf_purge_hash(struct cli *cli, const char * const *av, void *priv)
static void static void
ccf_purge_list(struct cli *cli, const char * const *av, void *priv) ccf_purge_list(struct cli *cli, const char * const *av, void *priv)
{ {
struct ban *b0; struct ban *b;
struct ban_test *bt; struct ban_test *bt;
(void)av; (void)av;
(void)priv; (void)priv;
/*
* XXX: Strictly speaking, this loop traversal is not lock-safe Lck_Lock(&ban_mtx);
* XXX: because we might inspect the last ban while it gets VTAILQ_LAST(&ban_head, banhead)->refcount++;
* XXX: destroyed. To properly fix this, we would need to either Lck_Unlock(&ban_mtx);
* XXX: hold the lock over the entire loop, or grab refcounts
* XXX: under lock for each element of the list. VTAILQ_FOREACH(b, &ban_head, list) {
* XXX: We do neither, and hope for the best. bt = VTAILQ_FIRST(&b->tests);
*/ cli_out(cli, "%5u %4s\t%s\n",
for (b0 = ban_start; b0 != NULL; b0 = VTAILQ_NEXT(b0, list)) { b->refcount, b->flags ? "Gone" : "", bt->test);
if (b0->refcount == 0 && VTAILQ_NEXT(b0, list) == NULL) do {
break; bt = VTAILQ_NEXT(bt, list);
VTAILQ_FOREACH(bt, &b0->tests, list) if (bt != NULL)
cli_out(cli, "%5u %d \"%s\"\n", cli_out(cli, "\t\t%s\n", bt->test);
b0->refcount, b0->flags, } while (bt != NULL);
bt->test);
} }
Lck_Lock(&ban_mtx);
VTAILQ_LAST(&ban_head, banhead)->refcount--;
Lck_Unlock(&ban_mtx);
} }
static struct cli_proto ban_cmds[] = { static struct cli_proto ban_cmds[] = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment