[master] f839d55 Use a condvar instead of a polling sleep to alert parent req that ESI include is off the waiting list.
Poul-Henning Kamp
phk at FreeBSD.org
Mon May 9 18:20:07 CEST 2016
commit f839d5586842094a2cea65a2ea7337cb2836f72c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon May 9 16:18:10 2016 +0000
Use a condvar instead of a polling sleep to alert parent req that
ESI include is off the waiting list.
Many thanks to Nils for pushing for us to fix this.
Superceedes #1902
diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index 876a0b6..fa944d0 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -42,7 +42,8 @@
#include "vend.h"
#include "vgz.h"
-static vtr_deliver_f VED_Deliver;
+static vtr_deliver_f ved_deliver;
+static vtr_reembark_f ved_reembark;
static const uint8_t gzip_hdr[] = {
0x1f, 0x8b, 0x08,
@@ -59,6 +60,7 @@ struct ecx {
int state;
ssize_t l;
int isgzip;
+ int woken;
struct req *preq;
ssize_t l_crc;
@@ -68,11 +70,28 @@ struct ecx {
static const struct transport VED_transport = {
.magic = TRANSPORT_MAGIC,
.name = "ESI_INCLUDE",
- .deliver = VED_Deliver,
+ .deliver = ved_deliver,
+ .reembark = ved_reembark,
};
/*--------------------------------------------------------------------*/
+static void __match_proto__(vtr_reembark_f)
+ved_reembark(struct worker *wrk, struct req *req)
+{
+ struct ecx *ecx;
+
+ (void)wrk;
+ CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+ CAST_OBJ_NOTNULL(ecx, req->transport_priv, ECX_MAGIC);
+ Lck_Lock(&req->sp->mtx);
+ ecx->woken = 1;
+ AZ(pthread_cond_signal(&ecx->preq->wrk->cond));
+ Lck_Unlock(&req->sp->mtx);
+}
+
+/*--------------------------------------------------------------------*/
+
static void
ved_include(struct req *preq, const char *src, const char *host,
struct ecx *ecx)
@@ -140,7 +159,6 @@ ved_include(struct req *preq, const char *src, const char *host,
req->vcl = preq->vcl;
preq->vcl = NULL;
- req->wrk = preq->wrk;
/*
* XXX: We should decide if we should cache the director
@@ -163,14 +181,20 @@ ved_include(struct req *preq, const char *src, const char *host,
while (1) {
req->wrk = wrk;
+ ecx->woken = 0;
s = CNT_Request(wrk, req);
if (s == REQ_FSM_DONE)
break;
DSL(DBG_WAITINGLIST, req->vsl->wid,
"loop waiting for ESI (%d)", (int)s);
assert(s == REQ_FSM_DISEMBARK);
+ Lck_Lock(&req->sp->mtx);
+ if (!ecx->woken)
+ (void)Lck_CondWait(
+ &ecx->preq->wrk->cond, &req->sp->mtx, 0);
+ Lck_Unlock(&req->sp->mtx);
+ ecx->woken = 0;
AZ(req->wrk);
- (void)usleep(10000);
}
VRTPRIV_dynamic_kill(req->sp->privs, (uintptr_t)req);
@@ -748,7 +772,7 @@ ved_vdp_bytes(struct req *req, enum vdp_action act, void **priv,
/*--------------------------------------------------------------------*/
static void __match_proto__(vtr_deliver_f)
-VED_Deliver(struct req *req, struct boc *boc, int wantbody)
+ved_deliver(struct req *req, struct boc *boc, int wantbody)
{
int i;
struct ecx *ecx;
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 3c2cdcb..15617a7 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -334,7 +334,7 @@ hsh_insert_busyobj(struct worker *wrk, struct objhead *oh)
enum lookup_e
HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp,
- int wait_for_busy, int always_insert)
+ int always_insert)
{
struct worker *wrk;
struct objhead *oh;
@@ -483,14 +483,9 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp,
AZ(req->hash_ignore_busy);
- if (wait_for_busy) {
- VTAILQ_INSERT_TAIL(&oh->waitinglist, req, w_list);
- if (DO_DEBUG(DBG_WAITINGLIST))
- VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh);
- } else {
- if (DO_DEBUG(DBG_WAITINGLIST))
- VSLb(req->vsl, SLT_Debug, "hit busy obj <%p>", oh);
- }
+ VTAILQ_INSERT_TAIL(&oh->waitinglist, req, w_list);
+ if (DO_DEBUG(DBG_WAITINGLIST))
+ VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh);
wrk->stats->busy_sleep++;
/*
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 72f24a7..f057e26 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -367,10 +367,7 @@ cnt_lookup(struct worker *wrk, struct req *req)
AZ(req->objcore);
if (req->hash_objhead)
had_objhead = 1;
- lr = HSH_Lookup(req, &oc, &busy,
- req->esi_level == 0 ? 1 : 0,
- req->hash_always_miss ? 1 : 0
- );
+ lr = HSH_Lookup(req, &oc, &busy, req->hash_always_miss ? 1 : 0);
if (lr == HSH_BUSY) {
/*
* We lost the session to a busy object, disembark the
@@ -777,7 +774,7 @@ cnt_purge(struct worker *wrk, struct req *req)
VRY_Prep(req);
AZ(req->objcore);
- lr = HSH_Lookup(req, &oc, &boc, 1, 1);
+ lr = HSH_Lookup(req, &oc, &boc, 1);
assert (lr == HSH_MISS);
AZ(oc);
CHECK_OBJ_NOTNULL(boc, OBJCORE_MAGIC);
diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h
index db4510b..7743dec 100644
--- a/bin/varnishd/hash/hash_slinger.h
+++ b/bin/varnishd/hash/hash_slinger.h
@@ -63,7 +63,7 @@ enum lookup_e {
struct ban;
void HSH_Cleanup(struct worker *w);
enum lookup_e HSH_Lookup(struct req *, struct objcore **, struct objcore **,
- int wait_for_busy, int always_insert);
+ int always_insert);
void HSH_Ref(struct objcore *o);
void HSH_Init(const struct hash_slinger *slinger);
void HSH_AddString(struct req *, void *ctx, const char *str);
More information about the varnish-commit
mailing list