diff options
author | Emre Ucan <eucan@de.adit-jv.com> | 2016-04-04 16:01:58 +0200 |
---|---|---|
committer | Wataru Natsume <wataru_natsume@xddp.denso.co.jp> | 2016-04-07 19:42:07 +0900 |
commit | 7e83b9984383f5107d8068705ee14ba4fd8f49a8 (patch) | |
tree | 367927bcbd5df3e34c416f5be791d081705d5d15 | |
parent | 8d3db3d9a04e1c85ad4f0647cc48efd8150f5e7e (diff) | |
download | wayland-ivi-extension-7e83b9984383f5107d8068705ee14ba4fd8f49a8.tar.gz |
ivi-controller: wait clients before freeing ivisurf
We have to wait before freeing ivisurf that all clients destroy
their proxies. Otherwise, a client could send an event to the ivisurf
just after we destroyed it. This would cause a race condition and
potentially SEGV.
Signed-off-by: Emre Ucan <eucan@de.adit-jv.com>
-rw-r--r-- | weston-ivi-shell/src/ivi-controller-impl.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/weston-ivi-shell/src/ivi-controller-impl.c b/weston-ivi-shell/src/ivi-controller-impl.c index 49069c8..b7a9c48 100644 --- a/weston-ivi-shell/src/ivi-controller-impl.c +++ b/weston-ivi-shell/src/ivi-controller-impl.c @@ -633,8 +633,14 @@ controller_surface_destroy(struct wl_client *client, int32_t destroy_scene_object) { (void)client; - (void)destroy_scene_object; + struct ivisurface *ivisurf = wl_resource_get_user_data(resource); + wl_resource_destroy(resource); + + if (wl_list_empty(&ivisurf->resource_list) && destroy_scene_object) { + wl_list_remove(&ivisurf->link); + free(ivisurf); + } } static const @@ -1341,12 +1347,17 @@ surface_event_remove(struct ivi_layout_surface *layout_surface, return; } - wl_resource_for_each(resource, &ivisurf->resource_list) { - ivi_controller_surface_send_destroyed(resource); + /*If there is no ivi_controller_surface objects, free + * ivisurf immediately. Otherwise wait for clients to destroy + * their proxies. */ + if (wl_list_empty(&ivisurf->resource_list)) { + wl_list_remove(&ivisurf->link); + free(ivisurf); + } else { + wl_resource_for_each(resource, &ivisurf->resource_list) { + ivi_controller_surface_send_destroyed(resource); + } } - - wl_list_remove(&ivisurf->link); - free(ivisurf); } static void |