[master] 03d3f82 Check if events we received are actually being waited for

Nils Goroll nils.goroll at uplex.de
Mon Nov 14 13:14:05 CET 2016


commit 03d3f82a452846920863b53d4c67797a410385b2
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Thu Nov 3 12:11:54 2016 +0100

    Check if events we received are actually being waited for
    
    For epoll, we tolerate spurious reports, for all other waiters
    we assert.
    
    fixes #2117

diff --git a/bin/varnishd/waiter/cache_waiter.c b/bin/varnishd/waiter/cache_waiter.c
index 80def71..f05a865 100644
--- a/bin/varnishd/waiter/cache_waiter.c
+++ b/bin/varnishd/waiter/cache_waiter.c
@@ -97,13 +97,15 @@ Wait_HeapInsert(const struct waiter *w, struct waited *wp)
  * XXX: any harm to come from it.  Caveat Emptor.
  */
 
-void
+int
 Wait_HeapDelete(const struct waiter *w, const struct waited *wp)
 {
 	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
 	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
-	if (wp->idx != BINHEAP_NOIDX)
-		binheap_delete(w->heap, wp->idx);
+	if (wp->idx == BINHEAP_NOIDX)
+		return (0);
+	binheap_delete(w->heap, wp->idx);
+	return (1);
 }
 
 double
diff --git a/bin/varnishd/waiter/cache_waiter_epoll.c b/bin/varnishd/waiter/cache_waiter_epoll.c
index 0997979..6b6d39b 100644
--- a/bin/varnishd/waiter/cache_waiter_epoll.c
+++ b/bin/varnishd/waiter/cache_waiter_epoll.c
@@ -26,6 +26,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
+ * Recommended reading: libev(3) "EVBACKEND_EPOLL" section
+ * - thank you, Marc Alexander Lehmann
  */
 
 //lint -e{766}
@@ -73,7 +75,7 @@ vwe_thread(void *priv)
 	struct waited *wp;
 	struct waiter *w;
 	double now, then;
-	int i, n;
+	int i, n, active;
 	struct vwe *vwe;
 	char c;
 
@@ -101,7 +103,7 @@ vwe_thread(void *priv)
 			CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
 			AZ(epoll_ctl(vwe->epfd, EPOLL_CTL_DEL, wp->fd, NULL));
 			vwe->nwaited--;
-			Wait_HeapDelete(w, wp);
+			AN(Wait_HeapDelete(w, wp));
 			Lck_Unlock(&vwe->mtx);
 			Wait_Call(w, wp, WAITER_TIMEOUT, now);
 		}
@@ -125,8 +127,12 @@ vwe_thread(void *priv)
 			}
 			CAST_OBJ_NOTNULL(wp, ep->data.ptr, WAITED_MAGIC);
 			Lck_Lock(&vwe->mtx);
-			Wait_HeapDelete(w, wp);
+			active = Wait_HeapDelete(w, wp);
 			Lck_Unlock(&vwe->mtx);
+			if (! active) {
+				VSL(SLT_Debug, wp->fd, "epoll: spurious event");
+				continue;
+			}
 			AZ(epoll_ctl(vwe->epfd, EPOLL_CTL_DEL, wp->fd, NULL));
 			vwe->nwaited--;
 			if (ep->events & EPOLLIN)
diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c
index e1c7642..42d5245 100644
--- a/bin/varnishd/waiter/cache_waiter_kqueue.c
+++ b/bin/varnishd/waiter/cache_waiter_kqueue.c
@@ -98,7 +98,7 @@ vwk_thread(void *priv)
 			CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
 			EV_SET(ke, wp->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
 			AZ(kevent(vwk->kq, ke, 1, NULL, 0, NULL));
-			Wait_HeapDelete(w, wp);
+			AN(Wait_HeapDelete(w, wp));
 			Lck_Unlock(&vwk->mtx);
 			Wait_Call(w, wp, WAITER_TIMEOUT, now);
 		}
@@ -118,7 +118,7 @@ vwk_thread(void *priv)
 			}
 			CAST_OBJ_NOTNULL(wp, ke[j].udata, WAITED_MAGIC);
 			Lck_Lock(&vwk->mtx);
-			Wait_HeapDelete(w, wp);
+			AN(Wait_HeapDelete(w, wp));
 			Lck_Unlock(&vwk->mtx);
 			vwk->nwaited--;
 			if (kp->flags & EV_EOF)
diff --git a/bin/varnishd/waiter/cache_waiter_poll.c b/bin/varnishd/waiter/cache_waiter_poll.c
index 5e2edb8..ed3a39c 100644
--- a/bin/varnishd/waiter/cache_waiter_poll.c
+++ b/bin/varnishd/waiter/cache_waiter_poll.c
@@ -190,13 +190,13 @@ VSL(SLT_Debug, vwp->pollfd[i].fd, "POLL loop i=%d revents=0x%x", i, vwp->pollfd[
 				v--;
 			then = Wait_When(wp);
 			if (then <= now) {
-				Wait_HeapDelete(w, wp);
+				AN(Wait_HeapDelete(w, wp));
 				Wait_Call(w, wp, WAITER_TIMEOUT, now);
 				vwp_del(vwp, i);
 			} else if (vwp->pollfd[i].revents & POLLIN) {
 				assert(wp->fd > 0);
 				assert(wp->fd == vwp->pollfd[i].fd);
-				Wait_HeapDelete(w, wp);
+				AN(Wait_HeapDelete(w, wp));
 				Wait_Call(w, wp, WAITER_ACTION, now);
 				vwp_del(vwp, i);
 			} else {
diff --git a/bin/varnishd/waiter/cache_waiter_ports.c b/bin/varnishd/waiter/cache_waiter_ports.c
index f208f8a..5b11be3 100644
--- a/bin/varnishd/waiter/cache_waiter_ports.c
+++ b/bin/varnishd/waiter/cache_waiter_ports.c
@@ -128,7 +128,7 @@ vws_port_ev(struct vws *vws, struct waiter *w, port_event_t *ev, double now)
 		 *          threadID=129476&tstart=0
 		 */
 		vws_del(vws, wp->fd);
-		Wait_HeapDelete(w, wp);
+		AN(Wait_HeapDelete(w, wp));
 		Wait_Call(w, wp, ev->portev_events & POLLERR ?
 		    WAITER_REMCLOSE : WAITER_ACTION,
 		    now);
@@ -167,7 +167,7 @@ vws_thread(void *priv)
 			}
 			CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
 			vws_del(vws, wp->fd);
-			Wait_HeapDelete(w, wp);
+			AN(Wait_HeapDelete(w, wp));
 			Wait_Call(w, wp, WAITER_TIMEOUT, now);
 		}
 		then = vws->next - now;
diff --git a/bin/varnishd/waiter/waiter_priv.h b/bin/varnishd/waiter/waiter_priv.h
index c7d1d25..6db06ca 100644
--- a/bin/varnishd/waiter/waiter_priv.h
+++ b/bin/varnishd/waiter/waiter_priv.h
@@ -78,5 +78,5 @@ Wait_When(const struct waited *wp)
 void Wait_Call(const struct waiter *, struct waited *,
     enum wait_event ev, double now);
 void Wait_HeapInsert(const struct waiter *, struct waited *);
-void Wait_HeapDelete(const struct waiter *, const struct waited *);
+int Wait_HeapDelete(const struct waiter *, const struct waited *);
 double Wait_HeapDue(const struct waiter *, struct waited **);



More information about the varnish-commit mailing list