Commit 84c940a8 authored by Tollef Fog Heen's avatar Tollef Fog Heen

Merge r4668: Add a, for now, unsupported & experimental facility.

See test-case for details.


git-svn-id: http://www.varnish-cache.org/svn/branches/2.1@4703 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent acef6805
......@@ -308,6 +308,8 @@ HSH_Insert(const struct sess *sp)
return (oc);
}
/**********************************************************************
*/
struct objcore *
HSH_Lookup(struct sess *sp, struct objhead **poh)
......@@ -353,8 +355,8 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
VTAILQ_FOREACH(oc, &oh->objcs, list) {
/* Must be at least our own ref + the objcore we examine */
assert(oh->refcnt > 1);
assert(oc->objhead == oh);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
assert(oc->objhead == oh);
if (oc->flags & OC_F_PERSISTENT)
SMP_Fixup(sp, oh, oc);
......@@ -455,6 +457,9 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
return (oc);
}
/**********************************************************************
*/
static void
hsh_rush(struct objhead *oh)
{
......@@ -482,6 +487,56 @@ hsh_rush(struct objhead *oh)
}
}
/**********************************************************************
* Purge an entire objhead
*/
void
HSH_Purge(struct sess *sp, struct objhead *oh, double ttl, double grace)
{
struct objcore *oc, **ocp;
unsigned spc, nobj, n;
struct object *o;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
spc = WS_Reserve(sp->wrk->ws, 0);
ocp = (void*)sp->wrk->ws->f;
Lck_Lock(&oh->mtx);
assert(oh->refcnt > 0);
nobj = 0;
VTAILQ_FOREACH(oc, &oh->objcs, list) {
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
assert(oc->objhead == oh);
if (oc->flags & OC_F_PERSISTENT)
SMP_Fixup(sp, oh, oc);
xxxassert(spc >= sizeof *ocp);
oc->refcnt++;
spc -= sizeof *ocp;
ocp[nobj++] = oc;
}
Lck_Unlock(&oh->mtx);
if (ttl <= 0)
ttl = -1;
for (n = 0; n < nobj; n++) {
oc = ocp[n];
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
o = oc->obj;
if (o == NULL)
continue;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
o->ttl = sp->t_req + ttl;
if (!isnan(grace))
o->grace = grace;
EXP_Rearm(o);
HSH_Deref(sp->wrk, &o);
}
WS_Release(sp->wrk->ws, 0);
}
/**********************************************************************
* Kill a busy object we don't need anyway.
* There may be sessions on the waiting list, so we cannot just blow
......
......@@ -1023,6 +1023,19 @@ VRT_ban_string(struct sess *sp, const char *str, ...)
FreeArgv(av);
}
/*--------------------------------------------------------------------
* "real" purges
*/
void
VRT_purge(struct sess *sp, double ttl, double grace)
{
if (sp->cur_method == VCL_MET_HIT)
HSH_Purge(sp, sp->obj->objcore->objhead, ttl, grace);
else if (sp->cur_method == VCL_MET_MISS)
HSH_Purge(sp, sp->objcore->objhead, ttl, grace);
}
/*--------------------------------------------------------------------
* Simple stuff
*/
......
# $Id$
test "real purges"
server s1 {
rxreq
txresp -hdr "Vary: foo" -bodylen 1
rxreq
txresp -hdr "Vary: foo" -bodylen 2
rxreq
txresp -hdr "Vary: foo" -bodylen 3
rxreq
txresp -hdr "Vary: foo" -bodylen 4
rxreq
txresp -hdr "Vary: foo" -bodylen 5
rxreq
txresp -hdr "Vary: foo" -bodylen 6
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.request == "PURGE") {
return (lookup);
}
}
sub vcl_hit {
if (req.request == "PURGE") {
C{ VRT_purge(sp, 0, 0); }C
error 456 "got it";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
C{ VRT_purge(sp, 0, 0); }C
error 456 "got it";
}
}
} -start
client c1 {
txreq -hdr "foo: bar1"
rxresp
expect resp.bodylen == 1
txreq -hdr "foo: bar2"
rxresp
expect resp.bodylen == 2
txreq -hdr "foo: bar1"
rxresp
expect resp.bodylen == 1
txreq -hdr "foo: bar2"
rxresp
expect resp.bodylen == 2
txreq -req "PURGE" -hdr "foo: bar1"
rxresp
expect resp.status == 456
} -run
client c1 {
txreq -hdr "foo: bar1"
rxresp
expect resp.bodylen == 3
txreq -hdr "foo: bar2"
rxresp
expect resp.bodylen == 4
txreq -req "PURGE" -hdr "foo: bar3"
rxresp
expect resp.status == 456
} -run
client c1 {
txreq -hdr "foo: bar1"
rxresp
expect resp.bodylen == 5
txreq -hdr "foo: bar2"
rxresp
expect resp.bodylen == 6
} -run
......@@ -138,6 +138,7 @@ const char *VRT_regsub(const struct sess *sp, int all, const char *,
void VRT_panic(struct sess *sp, const char *, ...);
void VRT_ban(struct sess *sp, char *, ...);
void VRT_ban_string(struct sess *sp, const char *, ...);
void VRT_purge(struct sess *sp, double ttl, double grace);
void VRT_count(const struct sess *, unsigned);
int VRT_rewrite(const char *, const char *);
......
......@@ -227,8 +227,8 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI");
vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT");
vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n");
vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 4428 2010-01-06 17:");
vsb_cat(sb, "38:59Z tfheen $\n *\n * Runtime support for compiled V");
vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 4695 2010-04-19 13:");
vsb_cat(sb, "03:14Z tfheen $\n *\n * Runtime support for compiled V");
vsb_cat(sb, "CL programs.\n *\n * XXX: When this file is changed, l");
vsb_cat(sb, "ib/libvcl/vcc_gen_fixed_token.tcl\n");
vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n");
......@@ -281,8 +281,9 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, "\nvoid VRT_panic(struct sess *sp, const char *, ...);\n");
vsb_cat(sb, "void VRT_ban(struct sess *sp, char *, ...);\n");
vsb_cat(sb, "void VRT_ban_string(struct sess *sp, const char *, ...");
vsb_cat(sb, ");\n\nvoid VRT_count(const struct sess *, unsigned);\n");
vsb_cat(sb, "int VRT_rewrite(const char *, const char *);\n");
vsb_cat(sb, ");\nvoid VRT_purge(struct sess *sp, double ttl, double");
vsb_cat(sb, " grace);\n\nvoid VRT_count(const struct sess *, unsign");
vsb_cat(sb, "ed);\nint VRT_rewrite(const char *, const char *);\n");
vsb_cat(sb, "void VRT_error(struct sess *, unsigned, const char *);");
vsb_cat(sb, "\nint VRT_switch_config(const char *);\n");
vsb_cat(sb, "\nenum gethdr_e { HDR_REQ, HDR_RESP, HDR_OBJ, HDR_BERE");
......
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