[master] 6a04b34 Tell the waiter (if necessary) that we steal a filedescriptor, not all of them find out on their own.

Poul-Henning Kamp phk at FreeBSD.org
Fri Jan 23 12:49:00 CET 2015


commit 6a04b34eb544d7f547de93d8c1700d6dd56fc031
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Jan 23 11:48:31 2015 +0000

    Tell the waiter (if necessary) that we steal a filedescriptor, not
    all of them find out on their own.

diff --git a/bin/varnishd/cache/cache_backend_tcp.c b/bin/varnishd/cache/cache_backend_tcp.c
index a622193..cf7110e 100644
--- a/bin/varnishd/cache/cache_backend_tcp.c
+++ b/bin/varnishd/cache/cache_backend_tcp.c
@@ -384,6 +384,8 @@ VBT_Get(struct tcp_pool *tp, double tmo)
 		CHECK_OBJ_NOTNULL(vbc, VBC_MAGIC);
 
 		assert(vbc->in_waiter == VBC_W_INWAIT);
+VSL(SLT_Debug, 0, "------> Steal fd %d", vbc->fd);
+		Wait_Steal(tp->waiter, vbc->waited);
 		vbc->in_waiter = VBC_W_STOLEN;
 		pfd.fd = vbc->fd;
 		pfd.events = POLLIN;
diff --git a/bin/varnishd/waiter/cache_waiter.c b/bin/varnishd/waiter/cache_waiter.c
index ab07081..f609b06 100644
--- a/bin/varnishd/waiter/cache_waiter.c
+++ b/bin/varnishd/waiter/cache_waiter.c
@@ -203,6 +203,36 @@ Wait_Enter(const struct waiter *w, struct waited *wp)
 	return (0);
 }
 
+int
+Wait_Steal(const struct waiter *w, struct waited *wp)
+{
+	ssize_t written;
+	uintptr_t up;
+
+	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
+	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
+	assert(wp->fd > 0);		// stdin never comes here
+	AZ(w->dismantle);
+
+	if (w->impl->pass != NULL) {
+		INCOMPL();
+	}
+
+	assert(w->pipes[1] > 0);
+
+	if (w->impl->evict == NULL)
+		return (0);
+
+	up = (uintptr_t)wp;
+	AZ(up & 1);
+	up |= 1;
+	written = write(w->pipes[1], &up, sizeof up);
+	if (written != sizeof up && (errno == EAGAIN || errno == EWOULDBLOCK))
+		return (-1);
+	assert (written == sizeof up);
+	return (0);
+}
+
 static void
 wait_updidle(struct waiter *w, double now)
 {
@@ -226,6 +256,7 @@ Wait_Handle(struct waiter *w, struct waited *wp, enum wait_event ev, double now)
 	uintptr_t ss[NEV];
 	struct waited *wp2;
 	int i, j, dotimer = 0;
+	int steal;
 
 	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
 	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
@@ -253,9 +284,17 @@ Wait_Handle(struct waiter *w, struct waited *wp, enum wait_event ev, double now)
 			AN(w->dismantle);
 			continue;
 		}
+		steal = ss[j] & 1;
+		ss[j] &= ~1;
 		CAST_OBJ_NOTNULL(wp2, (void*)ss[j], WAITED_MAGIC);
 		if (wp2 == w->pipe_w) {
 			dotimer = 1;
+		} else if (steal) {
+			assert(wp2->fd >= 0);
+			VTAILQ_REMOVE(&w->waithead, wp2, list);
+			AN (w->impl->evict);
+			w->impl->evict(w, wp2);
+			w->func(wp2, WAITER_ACTION, now);
 		} else {
 			assert(wp2->fd >= 0);
 			VTAILQ_INSERT_TAIL(&w->waithead, wp2, list);
diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c
index d371d7e..0e4b263 100644
--- a/bin/varnishd/waiter/cache_waiter_kqueue.c
+++ b/bin/varnishd/waiter/cache_waiter_kqueue.c
@@ -99,6 +99,17 @@ vwk_inject(const struct waiter *w, struct waited *wp)
 		vwk_kq_sess(vwk, wp, EV_ADD | EV_ONESHOT);
 }
 
+#if 0
+static void
+vwk_evict(const struct waiter *w, struct waited *wp)
+{
+	struct vwk *vwk;
+
+	CAST_OBJ_NOTNULL(vwk, w->priv, VWK_MAGIC);
+	vwk_kq_sess(vwk, wp, EV_DELETE);
+}
+#endif
+
 /*--------------------------------------------------------------------*/
 
 static void
@@ -193,6 +204,7 @@ const struct waiter_impl waiter_kqueue = {
 	.init =		vwk_init,
 	.fini =		vwk_fini,
 	.inject =	vwk_inject,
+	// .evict =	vwk_evict,
 	.size =		sizeof(struct vwk),
 };
 
diff --git a/bin/varnishd/waiter/waiter.h b/bin/varnishd/waiter/waiter.h
index 953df8e..31923d7 100644
--- a/bin/varnishd/waiter/waiter.h
+++ b/bin/varnishd/waiter/waiter.h
@@ -58,6 +58,7 @@ typedef void waiter_handle_f(struct waited *, enum wait_event, double now);
 
 /* cache_waiter.c */
 int Wait_Enter(const struct waiter *, struct waited *);
+int Wait_Steal(const struct waiter *, struct waited *);
 struct waiter *Wait_New(waiter_handle_f *, volatile double *timeout);
 void Wait_Destroy(struct waiter **);
 const char *Wait_GetName(void);



More information about the varnish-commit mailing list