From: Changyeon Lee Date: Thu, 11 Nov 2021 04:11:49 +0000 (+0900) Subject: e_comp_wl_renderer: fix leak of E_Comp_Wl_Renderer_Surface X-Git-Tag: accepted/tizen/unified/20211117.130407~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5284e28db6046472e55d53cec0ddcb04aeef4a72;p=platform%2Fupstream%2Fenlightenment.git e_comp_wl_renderer: fix leak of E_Comp_Wl_Renderer_Surface 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 --- diff --git a/src/bin/e_comp_wl_renderer.c b/src/bin/e_comp_wl_renderer.c index ed6dbd2..c467264 100644 --- a/src/bin/e_comp_wl_renderer.c +++ b/src/bin/e_comp_wl_renderer.c @@ -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); }