Reviewed-By: Mike Blumenkrantz <zm...@osg.samsung.com>

On Wed, Apr 20, 2016 at 11:11 PM Jonas Ådahl <jad...@gmail.com> wrote:

> On client destruction, the shell object may be destroyed before the
> shell surface objects. If this happens to two surfaces of the same
> client, and one surface being destroyed results in the focus being
> switched to the other, this would trigger a ping event.
>
> The ping event sending function relies on having a valid owner, and if
> the shell would be destoryed prior to the shell surface, we'd crash in
> this function.
>
> Solve this by unsetting the owner pointer when the shell client goes
> away and early out in the ping event sending function if the owner is
> gone.
>
> Signed-off-by: Jonas Ådahl <jad...@gmail.com>
> ---
>  desktop-shell/shell.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index 24437d8..f705c99 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -2149,6 +2149,8 @@ ping_handler(struct weston_surface *surface,
> uint32_t serial)
>                 return;
>         if (shsurf->surface == shsurf->shell->grab_surface)
>                 return;
> +       if (!shsurf->owner)
> +               return;
>
>         handle_xdg_ping(shsurf, serial);
>  }
> @@ -3778,7 +3780,8 @@ shell_get_shell_surface(struct wl_client *client,
>         wl_resource_set_implementation(shsurf->resource,
>                                        &shell_surface_implementation,
>                                        shsurf,
> shell_destroy_shell_surface);
> -       wl_list_init(wl_resource_get_link(shsurf->resource));
> +       wl_list_insert(&sc->surface_list,
> +                      wl_resource_get_link(shsurf->resource));
>  }
>
>  static bool
> @@ -5864,6 +5867,8 @@ handle_shell_client_destroy(struct wl_listener
> *listener, void *data)
>  {
>         struct shell_client *sc =
>                 container_of(listener, struct shell_client,
> destroy_listener);
> +       struct wl_resource *shsurf_resource;
> +       struct shell_surface *shsurf;
>
>         if (sc->ping_timer)
>                 wl_event_source_remove(sc->ping_timer);
> @@ -5872,6 +5877,10 @@ handle_shell_client_destroy(struct wl_listener
> *listener, void *data)
>          * head of the surface list so we don't use that freed list node
>          * during surface clean up later on.
>          */
> +       wl_resource_for_each(shsurf_resource, &sc->surface_list) {
> +               shsurf = wl_resource_get_user_data(shsurf_resource);
> +               shsurf->owner = NULL;
> +       }
>         wl_list_remove(&sc->surface_list);
>
>         free(sc);
> --
> 2.5.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to