[PATCH xserver 2/3] xwayland: handle global object destruction

Kristian Høgsberg hoegsberg at gmail.com
Wed Aug 21 23:46:14 PDT 2013


On Wed, Aug 21, 2013 at 09:53:26AM +0200, Giovanni Campagna wrote:
> From: Giovanni Campagna <gcampagn at redhat.com>
> 
> Certain global objects, such as outputs, can be destroyed during
> the session. We must handle that and not crash.
> ---
>  hw/xfree86/xwayland/xwayland-drm.c     |  7 ++++++
>  hw/xfree86/xwayland/xwayland-input.c   |  7 ++++++
>  hw/xfree86/xwayland/xwayland-output.c  | 40 +++++++++++++++++++++++++++++++---
>  hw/xfree86/xwayland/xwayland-private.h |  6 ++++-
>  hw/xfree86/xwayland/xwayland.c         | 17 +++++++++++----
>  5 files changed, 69 insertions(+), 8 deletions(-)

This one and 1/3 looks good.  I've rebased the xwayland-1.12 branch
onto xserver master, cleaned it up a bit, filtered out non-xwayland
commits, squashed the development history of the rest and pushed to
upstream in the branch xwayland.  On top of that I've applied a patch
of my own and your 1/3 and 2/3 patches.  Patch 3/3 makes the server
not start for me (no screens found) so I've not pushed that.

There's an xwayland branch in the xf86-video-intel driver to go with
the rebased xwayland xserver.  This was a force push, the old xwayland
branch has been renamed to xwayland-1.12 to match the server branch it
works with.

Kristian

> diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
> index 1514ef5..bfa0b74 100644
> --- a/hw/xfree86/xwayland/xwayland-drm.c
> +++ b/hw/xfree86/xwayland/xwayland-drm.c
> @@ -119,8 +119,15 @@ drm_handler(void *data, struct wl_registry *registry, uint32_t id,
>      }
>  }
>  
> +static void
> +global_remove(void *data, struct wl_registry *registry, uint32_t name)
> +{
> +    /* Nothing to do here, wl_drm should not be removed */
> +}
> +
>  static const struct wl_registry_listener drm_listener = {
>      drm_handler,
> +    global_remove
>  };
>  
>  int
> diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
> index c550d77..eda2464 100644
> --- a/hw/xfree86/xwayland/xwayland-input.c
> +++ b/hw/xfree86/xwayland/xwayland-input.c
> @@ -600,8 +600,15 @@ input_handler(void *data, struct wl_registry *registry, uint32_t id,
>      }
>  }
>  
> +static void
> +global_remove(void *data, struct wl_registry *registry, uint32_t name)
> +{
> +    /* FIXME */
> +}
> +
>  static const struct wl_registry_listener input_listener = {
>      input_handler,
> +    global_remove,
>  };
>  
>  void
> diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
> index 8f087f6..3cfeb7f 100644
> --- a/hw/xfree86/xwayland/xwayland-output.c
> +++ b/hw/xfree86/xwayland/xwayland-output.c
> @@ -95,6 +95,14 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
>  {
>  }
>  
> +static void
> +crtc_destroy(xf86CrtcPtr crtc)
> +{
> +    /* Nothing to do here, we only destroy CRTCs when instructed to do
> +       so by wl_output changes
> +    */
> +}
> +
>  static const xf86CrtcFuncsRec crtc_funcs = {
>      .dpms                = crtc_dpms,
>      .set_mode_major      = crtc_set_mode_major,
> @@ -106,7 +114,7 @@ static const xf86CrtcFuncsRec crtc_funcs = {
>      .shadow_create       = crtc_shadow_create,
>      .shadow_allocate     = crtc_shadow_allocate,
>      .shadow_destroy      = crtc_shadow_destroy,
> -    .destroy		 = NULL, /* XXX */
> +    .destroy		 = crtc_destroy,
>  };
>  
>  static void
> @@ -246,7 +254,7 @@ display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
>      xwl_output->x = x;
>      xwl_output->y = y;
>  
> -    xwl_screen->xwl_output = xwl_output;
> +    xorg_list_append (&xwl_output->link, &xwl_screen->output_list);
>  }
>  
>  static void
> @@ -277,13 +285,39 @@ global_handler(void *data, struct wl_registry *registry, uint32_t id,
>  	xwl_output = xwl_output_create(xwl_screen);
>  	xwl_output->output = wl_registry_bind(registry, id,
>  	                                      &wl_output_interface, 1);
> +	xwl_output->name = id;
>  	wl_output_add_listener(xwl_output->output,
>  			       &output_listener, xwl_output);
>      }
>  }
>  
> +void
> +xwl_output_remove(struct xwl_output *xwl_output)
> +{
> +    xorg_list_del (&xwl_output->link);
> +    xf86OutputDestroy (xwl_output->xf86output);
> +    xf86CrtcDestroy (xwl_output->xf86crtc);
> +
> +    wl_output_destroy (xwl_output->output);
> +}
> +
> +static void
> +global_remove(void *data, struct wl_registry *registry, uint32_t name)
> +{
> +    struct xwl_screen *xwl_screen = data;
> +    struct xwl_output *xwl_output, *tmp;
> +
> +    xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) {
> +	if (xwl_output->name == name) {
> +	    xwl_output_remove(xwl_output);
> +	    break;
> +	}
> +    }
> +}  
> +
>  static const struct wl_registry_listener global_listener = {
>      global_handler,
> +    global_remove
>  };
>  
>  void
> @@ -299,7 +333,7 @@ xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrnin
>      wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
>                               xwl_screen);
>  
> -    while (!xwl_screen->xwl_output) {
> +    while (xwl_screen->output_list.next == &xwl_screen->output_list) {
>          ret = wl_display_roundtrip(xwl_screen->display);
>          if (ret == -1)
>              FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
> diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
> index e427316..7005db2 100644
> --- a/hw/xfree86/xwayland/xwayland-private.h
> +++ b/hw/xfree86/xwayland/xwayland-private.h
> @@ -44,7 +44,6 @@ struct xwl_screen {
>      ScrnInfoPtr			 scrninfo;
>      int				 drm_fd;
>      int				 wayland_fd;
> -    struct xwl_output		*xwl_output;
>      struct wl_display		*display;
>      struct wl_registry          *registry;
>      struct wl_registry          *drm_registry;
> @@ -58,6 +57,7 @@ struct xwl_screen {
>      uint32_t			 flags;
>      char			*device_name;
>      uint32_t			 authenticated;
> +    struct xorg_list		 output_list;
>      struct xorg_list		 seat_list;
>      struct xorg_list		 damage_window_list;
>      struct xorg_list		 window_list;
> @@ -74,12 +74,14 @@ struct xwl_screen {
>  };
>  
>  struct xwl_output {
> +    struct xorg_list             link;
>      struct wl_output		*output;
>      struct xwl_screen		*xwl_screen;
>      int32_t			 x, y, width, height;
>      xf86Monitor			 xf86monitor;
>      xf86OutputPtr		 xf86output;
>      xf86CrtcPtr			 xf86crtc;
> +    int32_t                      name;
>  };
>  
>  
> @@ -127,6 +129,8 @@ Bool xwl_drm_initialised(struct xwl_screen *screen);
>  
>  void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
>  
> +void xwl_output_remove(struct xwl_output *output);
> +
>  extern const struct xserver_listener xwl_server_listener;
>  
>  #endif /* _XWAYLAND_PRIVATE_H_ */
> diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
> index 880b7ec..2047a85 100644
> --- a/hw/xfree86/xwayland/xwayland.c
> +++ b/hw/xfree86/xwayland/xwayland.c
> @@ -103,8 +103,15 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
>      }
>  }
>  
> +static void
> +global_remove(void *data, struct wl_registry *registry, uint32_t name)
> +{
> +    /* Nothing to do here, wl_compositor and wl_shm should not be removed */
> +}
> +
>  static const struct wl_registry_listener registry_listener = {
>      registry_global,
> +    global_remove
>  };
>  
>  static void
> @@ -230,6 +237,7 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
>  	return FALSE;
>      }
>  
> +    xorg_list_init(&xwl_screen->output_list);
>      xorg_list_init(&xwl_screen->seat_list);
>      xorg_list_init(&xwl_screen->damage_window_list);
>      xorg_list_init(&xwl_screen->window_list);
> @@ -318,12 +326,13 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
>  
>  void xwl_screen_destroy(struct xwl_screen *xwl_screen)
>  {
> -    if (xwl_screen->xwl_output) {
> -	xf86OutputDestroy(xwl_screen->xwl_output->xf86output);
> -	xf86CrtcDestroy(xwl_screen->xwl_output->xf86crtc);
> +    struct xwl_output *xwl_output, *tmp;
> +
> +    xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) {
> +	xwl_output_remove(xwl_output);
> +	break;
>      }
>  
> -    free(xwl_screen->xwl_output);
>      free(xwl_screen);
>  }
>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list