summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmre Ucan <eucan@de.adit-jv.com>2016-04-05 17:01:13 +0200
committerWataru Natsume <wataru_natsume@xddp.denso.co.jp>2016-04-07 19:42:00 +0900
commit8d3db3d9a04e1c85ad4f0647cc48efd8150f5e7e (patch)
treee52b2852047f39b03aa50a270806ed5ce45f75ef
parentec05f5434dee2ace5320313054fc025be2530e37 (diff)
downloadwayland-ivi-extension-8d3db3d9a04e1c85ad4f0647cc48efd8150f5e7e.tar.gz
ivi-controller: wait clients before freeing ivilayer
We have to wait before freeing ivilayer that all clients destroy their proxies. Otherwise, a client could send an event to the ivilayer just after we destroyed it. This would cause a race condition and potentially SEGV. Furthermore, the layout_layer pointer of ivilayer set to NULL after ivilayer freed in the old implementation. Therefore, old implementation writes 4 bytes to invalid location. This implementation also solves the invalid write problem by moving the free code. Signed-off-by: Emre Ucan <eucan@de.adit-jv.com>
-rw-r--r--weston-ivi-shell/src/ivi-controller-impl.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/weston-ivi-shell/src/ivi-controller-impl.c b/weston-ivi-shell/src/ivi-controller-impl.c
index 15e677e..49069c8 100644
--- a/weston-ivi-shell/src/ivi-controller-impl.c
+++ b/weston-ivi-shell/src/ivi-controller-impl.c
@@ -802,15 +802,22 @@ controller_layer_destroy(struct wl_client *client,
{
struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
(void)client;
- (void)destroy_scene_object;
- if (ivilayer->layout_layer != NULL) {
- ivi_extension_layer_remove(ivilayer->shell, ivilayer->layout_layer);
- ivilayer->layout_layer = NULL;
- }
+ if (destroy_scene_object) {
+ if (ivilayer->layout_layer != NULL) {
+ ivi_extension_layer_remove(ivilayer->shell, ivilayer->layout_layer);
+ ivilayer->layout_layer = NULL;
+ }
- wl_resource_destroy(resource);
+ wl_resource_destroy(resource);
+ if (wl_list_empty(&ivilayer->resource_list)) {
+ wl_list_remove(&ivilayer->link);
+ free(ivilayer);
+ }
+ } else {
+ wl_resource_destroy(resource);
+ }
}
static const
@@ -1284,12 +1291,17 @@ layer_event_remove(struct ivi_layout_layer *layout_layer,
return;
}
- wl_resource_for_each(resource, &ivilayer->resource_list) {
+ /*If there is no ivi_controller_layer objects, free
+ * ivilayer immediately. Otherwise wait for clients to destroy
+ * their proxies. */
+ if (wl_list_empty(&ivilayer->resource_list)) {
+ wl_list_remove(&ivilayer->link);
+ free(ivilayer);
+ } else {
+ wl_resource_for_each(resource, &ivilayer->resource_list) {
ivi_controller_layer_send_destroyed(resource);
+ }
}
-
- wl_list_remove(&ivilayer->link);
- free(ivilayer);
}