[master] fcbc795 Add a "struct waited" for FD's being waited on, and make it possible to allocate it as part of the "real" structure owning the fd.

Poul-Henning Kamp phk at FreeBSD.org
Mon Jan 12 14:36:40 CET 2015


commit fcbc79510967d7a985bc00bfea20edcb8993f95f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jan 12 13:35:54 2015 +0000

    Add a "struct waited" for FD's being waited on, and make it possible
    to allocate it as part of the "real" structure owning the fd.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index ed654c8..7b8f14d 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -383,6 +383,19 @@ struct lru {
 	unsigned		n_objcore;
 };
 
+/* Connection waiter -------------------------------------------------
+ * Describing a file-descriptor/connection being waited on
+ */
+
+struct waited {
+	unsigned		magic;
+#define WAITED_MAGIC		0x1743992d
+	VTAILQ_ENTRY(waited)	list;
+	int			fd;
+	void			*ptr;
+	double			deadline;
+};
+
 /* Stored object -----------------------------------------------------
  * Pointer to a stored object, and the methods it supports
  */
@@ -647,7 +660,7 @@ struct sess {
 	struct sesspool		*sesspool;
 
 	struct pool_task	task;
-	VTAILQ_ENTRY(sess)	list;
+	struct waited		waited;
 
 	/* Session related fields ------------------------------------*/
 
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 6a65668..10bf5e9 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -40,7 +40,6 @@
 #include "vcli_priv.h"
 #include "vrnd.h"
 
-#include "waiter/waiter.h"
 #include "hash/hash_slinger.h"
 
 
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 4d46e32..7d9b17f 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -248,13 +248,13 @@ SES_ScheduleReq(struct req *req)
  */
 
 static void __match_proto__(waiter_handle_f)
-SES_Handle(void *ptr, int fd, enum wait_event ev, double now)
+ses_handle(struct waited *wp, enum wait_event ev, double now)
 {
 	struct sess *sp;
 	struct sesspool *pp;
 
-	CAST_OBJ_NOTNULL(sp, ptr, SESS_MAGIC);
-	(void)fd;
+	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
+	CAST_OBJ_NOTNULL(sp, wp->ptr, SESS_MAGIC);
 
 	switch (ev) {
 	case WAITER_TIMEOUT:
@@ -273,7 +273,7 @@ SES_Handle(void *ptr, int fd, enum wait_event ev, double now)
 			SES_Delete(sp, SC_OVERLOAD, now);
 		break;
 	default:
-		WRONG("Wrong event in SES_Handle");
+		WRONG("Wrong event in ses_handle");
 	}
 }
 
@@ -288,7 +288,11 @@ SES_Wait(struct sess *sp)
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	pp = sp->sesspool;
 	CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
-	if (WAIT_Enter(pp->http1_waiter, sp, sp->fd)) {
+	INIT_OBJ(&sp->waited, WAITED_MAGIC);
+	sp->waited.fd = sp->fd;
+	sp->waited.ptr = sp;
+	sp->waited.deadline = sp->t_idle;
+	if (WAIT_Enter(pp->http1_waiter, &sp->waited)) {
 		VSC_C_main->sess_pipe_overflow++;
 		SES_Delete(sp, SC_SESS_PIPE_OVERFLOW, NAN);
 	}
@@ -459,7 +463,7 @@ SES_NewPool(struct pool *wp, unsigned pool_no)
 	bprintf(nb, "sess%u", pool_no);
 	pp->mpl_sess = MPL_New(nb, &cache_param->sess_pool,
 	    &cache_param->workspace_session);
-	pp->http1_waiter = WAIT_Init(SES_Handle);
+	pp->http1_waiter = WAIT_Init(ses_handle);
 	return (pp);
 }
 
diff --git a/bin/varnishd/waiter/cache_waiter.c b/bin/varnishd/waiter/cache_waiter.c
index 93ce37c..20129bd 100644
--- a/bin/varnishd/waiter/cache_waiter.c
+++ b/bin/varnishd/waiter/cache_waiter.c
@@ -76,32 +76,21 @@ WAIT_Init(waiter_handle_f *func)
 }
 
 int
-WAIT_Enter(const struct waiter *w, void *ptr, int fd)
+WAIT_Enter(const struct waiter *w, struct waited *wp)
 {
-	struct sess *sp;
+	ssize_t written;
 
 	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
-	CAST_OBJ_NOTNULL(sp, ptr, SESS_MAGIC);
-	assert(fd >= 0);
-	assert(sp->fd >= 0);
+	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
+	assert(wp->fd >= 0);
 
 	if (w->impl->pass != NULL)
-		return (w->impl->pass(w->priv, sp));
+		return (w->impl->pass(w->priv, wp));
 	assert(w->pfd >= 0);
-	return (WAIT_Write_Session(sp, w->pfd));
-}
 
-/*
- * We do not make sp a const, in order to hint that we actually do take
- * control of it.
- */
-int __match_proto__()
-WAIT_Write_Session(struct sess *sp, int fd)
-{
-	ssize_t written;
-	written = write(fd, &sp, sizeof sp);
-	if (written != sizeof sp && (errno == EAGAIN || errno == EWOULDBLOCK))
+	written = write(w->pfd, &wp, sizeof wp);
+	if (written != sizeof wp && (errno == EAGAIN || errno == EWOULDBLOCK))
 		return (-1);
-	assert (written == sizeof sp);
+	assert (written == sizeof wp);
 	return (0);
 }
diff --git a/bin/varnishd/waiter/cache_waiter_epoll.c b/bin/varnishd/waiter/cache_waiter_epoll.c
index 67f6ce6..4df476e 100644
--- a/bin/varnishd/waiter/cache_waiter_epoll.c
+++ b/bin/varnishd/waiter/cache_waiter_epoll.c
@@ -61,7 +61,7 @@ struct vwe {
 
 	waiter_handle_f		*func;
 
-	VTAILQ_HEAD(,sess)	sesshead;
+	VTAILQ_HEAD(,waited)	sesshead;
 	int			pipes[2];
 	int			timer_pipes[2];
 };
@@ -81,7 +81,7 @@ vwe_modadd(struct vwe *vwe, int fd, void *data, short arm)
 		};
 		AZ(epoll_ctl(vwe->epfd, arm, fd, &ev));
 	} else {
-		struct sess *sp = (struct sess *)data;
+		struct waited *sp = (struct waited *)data;
 		CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 		sp->ev.data.ptr = data;
 		sp->ev.events = EPOLLIN | EPOLLPRI | EPOLLONESHOT | EPOLLRDHUP;
@@ -92,7 +92,7 @@ vwe_modadd(struct vwe *vwe, int fd, void *data, short arm)
 static void
 vwe_cond_modadd(struct vwe *vwe, int fd, void *data)
 {
-	struct sess *sp = (struct sess *)data;
+	struct waited *sp = (struct waited *)data;
 
 	assert(fd >= 0);
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
@@ -108,7 +108,7 @@ vwe_cond_modadd(struct vwe *vwe, int fd, void *data)
 static void
 vwe_eev(struct vwe *vwe, const struct epoll_event *ep, double now)
 {
-	struct sess *ss[NEEV], *sp;
+	struct waited *ss[NEEV], *sp;
 	int i, j;
 
 	AN(ep->data.ptr);
@@ -132,16 +132,16 @@ vwe_eev(struct vwe *vwe, const struct epoll_event *ep, double now)
 		CAST_OBJ_NOTNULL(sp, ep->data.ptr, SESS_MAGIC);
 		if (ep->events & EPOLLIN || ep->events & EPOLLPRI) {
 			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
-			vwe->func(sp, sp->fd, WAITER_ACTION, now);
+			vwe->func(sp, WAITER_ACTION, now);
 		} else if (ep->events & EPOLLERR) {
 			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
-			vwe->func(sp, sp->fd, WAITER_REMCLOSE, now);
+			vwe->func(sp, WAITER_REMCLOSE, now);
 		} else if (ep->events & EPOLLHUP) {
 			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
-			vwe->func(sp, sp->fd, WAITER_REMCLOSE, now);
+			vwe->func(sp, WAITER_REMCLOSE, now);
 		} else if (ep->events & EPOLLRDHUP) {
 			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
-			vwe->func(sp, sp->fd, WAITER_REMCLOSE, now);
+			vwe->func(sp, WAITER_REMCLOSE, now);
 		}
 	}
 }
@@ -152,7 +152,7 @@ static void *
 vwe_thread(void *priv)
 {
 	struct epoll_event ev[NEEV], *ep;
-	struct sess *sp;
+	struct waited *sp;
 	char junk;
 	double now, deadline;
 	int dotimer, i, n;
@@ -190,11 +190,11 @@ vwe_thread(void *priv)
 			sp = VTAILQ_FIRST(&vwe->sesshead);
 			if (sp == NULL)
 				break;
-			if (sp->t_idle > deadline)
+			if (sp->deadline > deadline)
 				break;
 			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
 			// XXX: not yet VTCP_linger(sp->fd, 0);
-			vwe->func(sp, sp->fd, WAITER_TIMEOUT, now);
+			vwe->func(sp, WAITER_TIMEOUT, now);
 		}
 	}
 	return (NULL);
diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c
index 7533109..f6fff9a 100644
--- a/bin/varnishd/waiter/cache_waiter_kqueue.c
+++ b/bin/varnishd/waiter/cache_waiter_kqueue.c
@@ -58,7 +58,7 @@ struct vwk {
 	int			kq;
 	struct kevent		ki[NKEV];
 	unsigned		nki;
-	VTAILQ_HEAD(,sess)	sesshead;
+	VTAILQ_HEAD(,waited)	sesshead;
 };
 
 /*--------------------------------------------------------------------*/
@@ -76,12 +76,11 @@ vwk_kq_flush(struct vwk *vwk)
 }
 
 static void
-vwk_kq_sess(struct vwk *vwk, struct sess *sp, short arm)
+vwk_kq_sess(struct vwk *vwk, struct waited *sp, short arm)
 {
 
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	CHECK_OBJ_NOTNULL(sp, WAITED_MAGIC);
 	assert(sp->fd >= 0);
-	DSL(DBG_WAITER, sp->vxid, "KQ: EV_SET sp %p arm %x", sp, arm);
 	EV_SET(&vwk->ki[vwk->nki], sp->fd, EVFILT_READ, arm, 0, 0, sp);
 	if (++vwk->nki == NKEV)
 		vwk_kq_flush(vwk);
@@ -93,7 +92,7 @@ static void
 vwk_pipe_ev(struct vwk *vwk, const struct kevent *kp)
 {
 	int i, j;
-	struct sess *ss[NKEV];
+	struct waited *ss[NKEV];
 
 	AN(kp->udata);
 	assert(kp->udata == vwk->pipes);
@@ -102,7 +101,7 @@ vwk_pipe_ev(struct vwk *vwk, const struct kevent *kp)
 	if (i == -1 && errno == EAGAIN)
 		return;
 	while (i >= sizeof ss[0]) {
-		CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC);
+		CHECK_OBJ_NOTNULL(ss[j], WAITED_MAGIC);
 		assert(ss[j]->fd >= 0);
 		VTAILQ_INSERT_TAIL(&vwk->sesshead, ss[j], list);
 		vwk_kq_sess(vwk, ss[j], EV_ADD | EV_ONESHOT);
@@ -117,28 +116,22 @@ vwk_pipe_ev(struct vwk *vwk, const struct kevent *kp)
 static void
 vwk_sess_ev(struct vwk *vwk, const struct kevent *kp, double now)
 {
-	struct sess *sp;
+	struct waited *sp;
 
 	AN(kp->udata);
 	assert(kp->udata != vwk->pipes);
-	CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC);
-	DSL(DBG_WAITER, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s",
-	    sp, (unsigned long)kp->data, kp->flags,
-	    (kp->flags & EV_EOF) ? " EOF" : "");
+	CAST_OBJ_NOTNULL(sp, kp->udata, WAITED_MAGIC);
 
 	if (kp->data > 0) {
 		VTAILQ_REMOVE(&vwk->sesshead, sp, list);
-		vwk->func(sp, sp->fd, WAITER_ACTION, now);
+		vwk->func(sp, WAITER_ACTION, now);
 		return;
 	} else if (kp->flags & EV_EOF) {
 		VTAILQ_REMOVE(&vwk->sesshead, sp, list);
-		vwk->func(sp, sp->fd, WAITER_REMCLOSE, now);
+		vwk->func(sp, WAITER_REMCLOSE, now);
 		return;
 	} else {
-		VSL(SLT_Debug, sp->vxid,
-		    "KQ: sp %p kev data %lu flags 0x%x%s",
-		    sp, (unsigned long)kp->data, kp->flags,
-		    (kp->flags & EV_EOF) ? " EOF" : "");
+		WRONG("unknown kqueue state");
 	}
 }
 
@@ -151,7 +144,7 @@ vwk_thread(void *priv)
 	struct kevent ke[NKEV], *kp;
 	int j, n, dotimer;
 	double now, deadline;
-	struct sess *sp;
+	struct waited *sp;
 
 	CAST_OBJ_NOTNULL(vwk, priv, VWK_MAGIC);
 	THR_SetName("cache-kqueue");
@@ -204,11 +197,11 @@ vwk_thread(void *priv)
 			sp = VTAILQ_FIRST(&vwk->sesshead);
 			if (sp == NULL)
 				break;
-			if (sp->t_idle > deadline)
+			if (sp->deadline > deadline)
 				break;
 			VTAILQ_REMOVE(&vwk->sesshead, sp, list);
 			// XXX: not yet (void)VTCP_linger(sp->fd, 0);
-			vwk->func(sp, sp->fd, WAITER_TIMEOUT, now);
+			vwk->func(sp, WAITER_TIMEOUT, now);
 		}
 	}
 	NEEDLESS_RETURN(NULL);
diff --git a/bin/varnishd/waiter/cache_waiter_poll.c b/bin/varnishd/waiter/cache_waiter_poll.c
index 37413d3..b347205 100644
--- a/bin/varnishd/waiter/cache_waiter_poll.c
+++ b/bin/varnishd/waiter/cache_waiter_poll.c
@@ -52,7 +52,7 @@ struct vwp {
 	unsigned		npoll;
 	unsigned		hpoll;
 
-	VTAILQ_HEAD(,sess)	sesshead;
+	VTAILQ_HEAD(,waited)	sesshead;
 };
 
 /*--------------------------------------------------------------------*/
@@ -125,7 +125,7 @@ vwp_main(void *priv)
 {
 	int v, v2;
 	struct vwp *vwp;
-	struct sess *ss[NEEV], *sp, *sp2;
+	struct waited *ss[NEEV], *sp, *sp2;
 	double now, deadline;
 	int i, j, fd;
 
@@ -149,7 +149,7 @@ vwp_main(void *priv)
 		VTAILQ_FOREACH_SAFE(sp, &vwp->sesshead, list, sp2) {
 			if (v != 0 && v2 == 0)
 				break;
-			CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+			CHECK_OBJ_NOTNULL(sp, WAITED_MAGIC);
 			fd = sp->fd;
 			assert(fd >= 0);
 			assert(fd <= vwp->hpoll);
@@ -160,12 +160,12 @@ vwp_main(void *priv)
 				vwp->pollfd[fd].revents = 0;
 				VTAILQ_REMOVE(&vwp->sesshead, sp, list);
 				vwp_unpoll(vwp, fd);
-				vwp->func(sp, sp->fd, WAITER_ACTION, now);
-			} else if (sp->t_idle <= deadline) {
+				vwp->func(sp, WAITER_ACTION, now);
+			} else if (sp->deadline <= deadline) {
 				VTAILQ_REMOVE(&vwp->sesshead, sp, list);
 				vwp_unpoll(vwp, fd);
 				// XXX: not yet (void)VTCP_linger(sp->fd, 0);
-				vwp->func(sp, sp->fd, WAITER_TIMEOUT, now);
+				vwp->func(sp, WAITER_TIMEOUT, now);
 			}
 		}
 		if (v2 && vwp->pollfd[vwp->pipes[0]].revents) {
@@ -180,7 +180,7 @@ vwp_main(void *priv)
 			assert(i >= 0);
 			AZ((unsigned)i % sizeof ss[0]);
 			for (j = 0; j * sizeof ss[0] < i; j++) {
-				CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC);
+				CHECK_OBJ_NOTNULL(ss[j], WAITED_MAGIC);
 				assert(ss[j]->fd >= 0);
 				VTAILQ_INSERT_TAIL(&vwp->sesshead, ss[j], list);
 				vwp_poll(vwp, ss[j]->fd);
diff --git a/bin/varnishd/waiter/cache_waiter_ports.c b/bin/varnishd/waiter/cache_waiter_ports.c
index d9c55b4..f6b1803 100644
--- a/bin/varnishd/waiter/cache_waiter_ports.c
+++ b/bin/varnishd/waiter/cache_waiter_ports.c
@@ -53,7 +53,7 @@ struct vws {
 	waiter_handle_f		*func;
 	pthread_t		ports_thread;
 	int			dport;
-	VTAILQ_HEAD(,sess)	sesshead;
+	VTAILQ_HEAD(,waited)	sesshead;
 };
 
 static inline void
@@ -74,20 +74,20 @@ vws_del(struct vws *vws, int fd)
 
 static inline void
 vws_port_ev(struct vws *vws, port_event_t *ev, double now) {
-	struct sess *sp;
+	struct waited *sp;
 	if(ev->portev_source == PORT_SOURCE_USER) {
-		CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC);
+		CAST_OBJ_NOTNULL(sp, ev->portev_user, WAITED_MAGIC);
 		assert(sp->fd >= 0);
 		VTAILQ_INSERT_TAIL(&vws->sesshead, sp, list);
 		vws_add(vws, sp->fd, sp);
 	} else {
 		assert(ev->portev_source == PORT_SOURCE_FD);
-		CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC);
+		CAST_OBJ_NOTNULL(sp, ev->portev_user, WAITED_MAGIC);
 		assert(sp->fd >= 0);
 		if(ev->portev_events & POLLERR) {
 			vws_del(vws, sp->fd);
 			VTAILQ_REMOVE(&vws->sesshead, sp, list);
-			vws->func(sp, sp->fd, WAITER_REMCLOSE, now);
+			vws->func(sp, WAITER_REMCLOSE, now);
 			return;
 		}
 
@@ -108,7 +108,7 @@ vws_port_ev(struct vws *vws, port_event_t *ev, double now) {
 		VTAILQ_REMOVE(&vws->sesshead, sp, list);
 
 		/* also handle errors */
-		vws->func(sp, sp->fd, WAITER_ACTION, now);
+		vws->func(sp, WAITER_ACTION, now);
 	}
 	return;
 }
@@ -116,7 +116,7 @@ vws_port_ev(struct vws *vws, port_event_t *ev, double now) {
 static void *
 vws_thread(void *priv)
 {
-	struct sess *sp;
+	struct waited *sp;
 	struct vws *vws;
 
 	CAST_OBJ_NOTNULL(vws, priv, VWS_MAGIC);
@@ -205,14 +205,14 @@ vws_thread(void *priv)
 			sp = VTAILQ_FIRST(&vws->sesshead);
 			if (sp == NULL)
 				break;
-			if (sp->t_idle > deadline) {
+			if (sp->deadline > deadline) {
 				break;
 			}
 			VTAILQ_REMOVE(&vws->sesshead, sp, list);
 			if(sp->fd != -1) {
 				vws_del(vws, sp->fd);
 			}
-			vws->func(sp, sp->fd, WAITER_TIMEOUT, now);
+			vws->func(sp, WAITER_TIMEOUT, now);
 		}
 
 		/*
@@ -241,7 +241,7 @@ vws_thread(void *priv)
 /*--------------------------------------------------------------------*/
 
 static int
-vws_pass(void *priv, struct sess *sp)
+vws_pass(void *priv, struct waited *sp)
 {
 	int r;
 	struct vws *vws;
diff --git a/bin/varnishd/waiter/waiter.h b/bin/varnishd/waiter/waiter.h
index 218eca5..4173e86 100644
--- a/bin/varnishd/waiter/waiter.h
+++ b/bin/varnishd/waiter/waiter.h
@@ -28,7 +28,7 @@
  *
  */
 
-struct sess;
+struct waited;
 struct waiter;
 
 enum wait_event {
@@ -37,9 +37,9 @@ enum wait_event {
 	WAITER_ACTION
 };
 
-typedef void waiter_handle_f(void *ptr, int fd, enum wait_event, double now);
+typedef void waiter_handle_f(struct waited *, enum wait_event, double now);
 typedef void* waiter_init_f(waiter_handle_f *, int *);
-typedef int waiter_pass_f(void *priv, struct sess *);
+typedef int waiter_pass_f(void *priv, struct waited *);
 
 #define WAITER_DEFAULT		"platform dependent"
 
@@ -50,10 +50,9 @@ struct waiter_impl {
 };
 
 /* cache_waiter.c */
-int WAIT_Enter(const struct waiter *, void *ptr, int fd);
+int WAIT_Enter(const struct waiter *, struct waited *);
 struct waiter *WAIT_Init(waiter_handle_f *);
 const char *WAIT_GetName(void);
-int WAIT_Write_Session(struct sess *sp, int fd);
 
 /* mgt_waiter.c */
 extern struct waiter_impl const * waiter;



More information about the varnish-commit mailing list