[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