e_comp_wl_renderer: fix leak of E_Comp_Wl_Renderer_Surface 85/266385/7
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 11 Nov 2021 04:11:49 +0000 (13:11 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Mon, 15 Nov 2021 04:28:50 +0000 (13:28 +0900)
1. free E_Comp_Wl_Renderer_Surface in listener of destroy request
2. clear ec of renderer_surface when it is freed

Change-Id: I5238cdeb558bfacd82de085629ed8762ad6e1168

src/bin/e_comp_wl_renderer.c

index ed6dbd2..c467264 100644 (file)
@@ -21,6 +21,8 @@ struct _E_Comp_Wl_Renderer_Surface
 {
    struct wl_resource *resource;
    E_Client *ec;
+   E_Object_Delfn *ec_delfn;
+   E_Comp_Wl_Renderer *renderer;
 };
 
 static E_Comp_Wl_Renderer_Manager *_renderer_mgr;
@@ -49,6 +51,53 @@ _renderer_surface_find(E_Client *ec)
 }
 
 static void
+_renderer_surface_cb_ec_free(void *data, void *obj)
+{
+   E_Comp_Wl_Renderer_Surface *renderer_surface;
+
+   renderer_surface = (E_Comp_Wl_Renderer_Surface *)data;
+   EINA_SAFETY_ON_NULL_RETURN(renderer_surface);
+
+   renderer_surface->ec = NULL;
+   renderer_surface->ec_delfn = NULL;
+}
+
+static void
+_renderer_surface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static const struct tizen_renderer_surface_interface renderer_surface_implementation = {
+   _renderer_surface_cb_destroy,
+};
+
+static void
+_renderer_surface_cb_resource_destroy(struct wl_resource *renderer_surface_resource)
+{
+   E_Comp_Wl_Renderer *renderer;
+   E_Comp_Wl_Renderer_Surface *renderer_surface;
+
+   renderer_surface = wl_resource_get_user_data(renderer_surface_resource);
+   if (!renderer_surface) return;
+
+   renderer = renderer_surface->renderer;
+   if (renderer)
+     {
+        renderer->renderer_surfaces = eina_list_remove(renderer->renderer_surfaces,
+                                                       renderer_surface);
+     }
+
+   if ((renderer_surface->ec) && (renderer_surface->ec_delfn))
+     {
+        e_object_delfn_del(E_OBJECT(renderer_surface->ec), renderer_surface->ec_delfn);
+        renderer_surface->ec_delfn = NULL;
+     }
+
+   E_FREE(renderer_surface);
+}
+
+static void
 _renderer_cb_get_renderer_surface(struct wl_client *client, struct wl_resource *resource,
                                   uint32_t id, struct wl_resource *surface_resource)
 {
@@ -78,7 +127,15 @@ _renderer_cb_get_renderer_surface(struct wl_client *client, struct wl_resource *
         return;
      }
 
+   wl_resource_set_implementation(renderer_surface->resource, &renderer_surface_implementation,
+                                  renderer_surface, _renderer_surface_cb_resource_destroy);
+
    renderer_surface->ec = ec;
+   renderer_surface->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
+                                                   _renderer_surface_cb_ec_free,
+                                                   renderer_surface);
+
+   renderer_surface->renderer = renderer;
    renderer->renderer_surfaces = eina_list_append(renderer->renderer_surfaces, renderer_surface);
 }
 
@@ -88,7 +145,6 @@ _renderer_cb_destroy(struct wl_client *client, struct wl_resource *resource)
    wl_resource_destroy(resource);
 }
 
-
 static const struct tizen_renderer_interface renderer_implementation = {
    _renderer_cb_get_renderer_surface,
    _renderer_cb_destroy,
@@ -99,6 +155,8 @@ _renderer_cb_resource_destroy(struct wl_resource *renderer_resource)
 {
    E_Comp_Wl_Renderer_Manager *renderer_mgr;
    E_Comp_Wl_Renderer *renderer;
+   E_Comp_Wl_Renderer_Surface *renderer_surface;
+   Eina_List *l;
 
    renderer = wl_resource_get_user_data(renderer_resource);
    if (!renderer) return;
@@ -107,6 +165,9 @@ _renderer_cb_resource_destroy(struct wl_resource *renderer_resource)
    if (renderer_mgr)
      renderer_mgr->renderers = eina_list_remove(renderer_mgr->renderers, renderer);
 
+   EINA_LIST_FOREACH(renderer->renderer_surfaces, l, renderer_surface)
+     renderer_surface->renderer = NULL;
+
    E_FREE(renderer);
 }