From 67fc5d68f967d19236221b2c0c2e0fe45acf560f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 13 Aug 2016 09:02:15 -0700 Subject: [PATCH] os: Abandon loop after poll call when array of fds has changed If a file descriptor is added or removed from an ospoll callback, then the arrays containing file descriptor information will have all of their indices changed, so the loop state is no longer consistent. Just bail out and let the caller come back around to try again. Signed-off-by: Keith Packard Reviewed-by: Peter Hutterer --- os/ospoll.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/os/ospoll.c b/os/ospoll.c index 2996ac7f4..b00d42202 100644 --- a/os/ospoll.c +++ b/os/ospoll.c @@ -82,6 +82,7 @@ struct ospoll { struct ospollfd *osfds; int num; int size; + Bool changed; }; #endif @@ -279,6 +280,7 @@ ospoll_add(struct ospoll *ospoll, int fd, array_insert(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos); array_insert(ospoll->osfds, ospoll->num, sizeof (ospoll->osfds[0]), pos); ospoll->num++; + ospoll->changed = TRUE; ospoll->fds[pos].fd = fd; ospoll->fds[pos].events = 0; @@ -316,6 +318,7 @@ ospoll_remove(struct ospoll *ospoll, int fd) array_delete(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos); array_delete(ospoll->osfds, ospoll->num, sizeof (ospoll->osfds[0]), pos); ospoll->num--; + ospoll->changed = TRUE; #endif } } @@ -408,6 +411,7 @@ ospoll_wait(struct ospoll *ospoll, int timeout) #endif #if POLL nready = xserver_poll(ospoll->fds, ospoll->num, timeout); + ospoll->changed = FALSE; if (nready > 0) { int f; for (f = 0; f < ospoll->num; f++) { @@ -427,6 +431,12 @@ ospoll_wait(struct ospoll *ospoll, int timeout) xevents |= X_NOTIFY_ERROR; ospoll->osfds[f].callback(ospoll->fds[f].fd, xevents, ospoll->osfds[f].data); + + /* Check to see if the arrays have changed, and just go back + * around again + */ + if (ospoll->changed) + break; } } }