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 <keithp@keithp.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
7d6fffb601
commit
67fc5d68f9
10
os/ospoll.c
10
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user