Commit 03d3f82a authored by Nils Goroll's avatar Nils Goroll

Check if events we received are actually being waited for

For epoll, we tolerate spurious reports, for all other waiters
we assert.

fixes #2117
parent 1a989e21
......@@ -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
......
......@@ -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)
......
......@@ -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)
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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 **);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment