[PATCH xserver 2/2] os: Abandon loop after poll call when array of fds has changed

Peter Hutterer peter.hutterer at who-t.net
Mon Aug 15 03:20:12 UTC 2016


On Sat, Aug 13, 2016 at 09:11:18AM -0700, Keith Packard wrote:
> 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 at keithp.com>
> ---
>  os/ospoll.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/os/ospoll.c b/os/ospoll.c
> index 2996ac7..902294d 100644
> --- a/os/ospoll.c
> +++ b/os/ospoll.c
> @@ -32,7 +32,7 @@
>  #include "ospoll.h"
>  #include "list.h"
>  
> -#if !HAVE_OSPOLL && HAVE_EPOLL_CREATE1
> +#if !HAVE_OSPOLL && HAVE_EPOLL_CREATE1 && 0

that looks like a leftover?  aside from that it looks good.

Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

Cheers,
   Peter

>  #include <sys/epoll.h>
>  #define EPOLL           1
>  #define HAVE_OSPOLL     1
> @@ -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;
>              }
>          }
>      }
> -- 
> 2.8.1
> 


More information about the xorg-devel mailing list