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