compositor: Release ds_surface_viewport when ds_surface is destroyed 73/313773/1
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 13 Jun 2024 01:19:34 +0000 (10:19 +0900)
committerSeunghun Lee <shiin.lee@samsung.com>
Tue, 2 Jul 2024 01:17:23 +0000 (10:17 +0900)
This is to fix abort by calling ds_surface_viewport_release() after
ds_surface has been destroyed.

The listeners added using e_surface_destroy_listener_add() have been
called in a hook handler E_CLIENT_HOOK_DEL, which is emitted when
e_object_del() is called for the associated E_Client. However, if
e_object_delay_del_ref() is called for the E_Client, the listeners for
E_CLIENT_HOOK_DEL would not be called immediately. Instead, it is
called when delay_del_ref count is dropped to zero by calling
e_object_delay_del_unref().

This means that listeners of e_surface_destroy_listener_add() can be
called after ds_surface is already freed, and the call to
ds_surface_viewport_release() in this case causes undefined behavior.

Change-Id: Ie8f316b2aef841c89386a41f19a4f5066d98d9bc

src/bin/e_compositor.c

index c4c7247b771100e4693d9314da3bc681fc0a3688..ea09ac519feabfdf133ce8a15945dd51dac2ff83 100644 (file)
@@ -1230,6 +1230,12 @@ _e_surface_cb_destroy(struct wl_listener *listener, void *data)
 
    surface = wl_container_of(listener, surface, destroy);
 
+   if (surface->surface_viewport)
+     {
+        ds_surface_viewport_release(surface->surface_viewport);
+        surface->surface_viewport = NULL;
+     }
+
    wl_list_remove(&surface->destroy.link);
    wl_list_remove(&surface->commit.link);
    wl_list_remove(&surface->new_subsurface.link);