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