[4.0] dbaba70 If workspace_thread is not be big enough to hold all the objcore pointers that need to be purged we iterate until done.
Lasse Karstensen
lkarsten at varnish-software.com
Tue Sep 23 15:09:29 CEST 2014
commit dbaba7024a9775175b588260287bf6588ed6da9e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Jul 28 10:00:15 2014 +0000
If workspace_thread is not be big enough to hold all the objcore pointers
that need to be purged we iterate until done.
Fixes #1551
Conflicts:
bin/varnishd/cache/cache_hash.c
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 76ad5c3..0a94a3d 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -559,49 +559,61 @@ HSH_Purge(struct worker *wrk, struct objhead *oh, double ttl, double grace,
double keep)
{
struct objcore *oc, **ocp;
- unsigned spc, nobj, n;
+ unsigned spc, ospc, nobj, n;
struct object *o;
+ int more = 0;
+
double now;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
- spc = WS_Reserve(wrk->aws, 0);
- ocp = (void*)wrk->aws->f;
- Lck_Lock(&oh->mtx);
- assert(oh->refcnt > 0);
- nobj = 0;
- now = VTIM_real();
- VTAILQ_FOREACH(oc, &oh->objcs, list) {
- CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
- assert(oc->objhead == oh);
- if (oc->flags & OC_F_BUSY) {
- /*
- * We cannot purge busy objects here, because their
- * owners have special rights to them, and may nuke
- * them without concern for the refcount, which by
- * definition always must be one, so they don't check.
- */
- continue;
+ ospc = WS_Reserve(wrk->aws, 0);
+ assert(ospc >= sizeof *ocp);
+ do {
+ more = 0;
+ spc = ospc;
+ nobj = 0;
+ ocp = (void*)wrk->aws->f;
+ Lck_Lock(&oh->mtx);
+ assert(oh->refcnt > 0);
+ now = VTIM_real();
+ VTAILQ_FOREACH(oc, &oh->objcs, list) {
+ CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+ assert(oc->objhead == oh);
+ if (oc->flags & OC_F_BUSY) {
+ /*
+ * We cannot purge busy objects here, because
+ * their owners have special rights to them,
+ * and may nuke them without concern for the
+ * refcount, which by definition always must
+ * be one, so they don't check.
+ */
+ continue;
+ }
+ if (oc->exp_flags & OC_EF_DYING)
+ continue;
+ if (spc < sizeof *ocp) {
+ /* Iterate if aws is not big enough */
+ more = 1;
+ break;
+ }
+ oc->refcnt++;
+ spc -= sizeof *ocp;
+ ocp[nobj++] = oc;
}
- if (oc->exp_flags & OC_EF_DYING)
- continue;
- xxxassert(spc >= sizeof *ocp);
- oc->refcnt++;
- spc -= sizeof *ocp;
- ocp[nobj++] = oc;
- }
- Lck_Unlock(&oh->mtx);
+ Lck_Unlock(&oh->mtx);
- for (n = 0; n < nobj; n++) {
- oc = ocp[n];
- CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
- o = oc_getobj(&wrk->stats, oc);
- if (o == NULL)
- continue;
- CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
- EXP_Rearm(o, now, ttl, grace, keep);
- (void)HSH_DerefObj(&wrk->stats, &o);
- }
+ for (n = 0; n < nobj; n++) {
+ oc = ocp[n];
+ CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+ o = oc_getobj(&wrk->stats, oc);
+ if (o == NULL)
+ continue;
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+ EXP_Rearm(o, now, ttl, grace, keep);
+ (void)HSH_DerefObj(&wrk->stats, &o);
+ }
+ } while (more);
WS_Release(wrk->aws, 0);
Pool_PurgeStat(nobj);
}
More information about the varnish-commit
mailing list