From 5847886a3fdb7c470bd55e215b822bbbaf109080 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 14 Jun 2019 16:43:23 -0700 Subject: [PATCH] ecore_evas: on internal Evas canvas uncontrolled death, properly clean up Ecore_Evas. This allow evas test to work with an Ecore_Evas directly. It prevent leaking of memory in the case of half destroying Ecore_Evas. Reviewed-by: Hermet Park Differential Revision: https://phab.enlightenment.org/D9104 --- src/lib/ecore_evas/ecore_evas.c | 22 +++++++++++++++++++++- src/lib/ecore_evas/ecore_evas_private.h | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 3e12ab5218..672b7c4072 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -77,6 +77,8 @@ static void _ecore_evas_animator_freeze(Ecore_Animator *animator); static void _ecore_evas_animator_thaw(Ecore_Animator *animator); static void *_ecore_evas_animator_del(Ecore_Animator *animator); +static void _ecore_evas_event_del(void *data, const Efl_Event *ev EINA_UNUSED); + static void _ecore_evas_focus_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *seat) { @@ -3432,6 +3434,12 @@ _ecore_evas_free(Ecore_Evas *ee) Efl_Input_Device *dev; Ecore_Evas_Interface *iface; + if (ee->self_del) + { + efl_event_callback_del(ee->evas, EFL_EVENT_INVALIDATE, _ecore_evas_event_del, ee); + ee->self_del = EINA_FALSE; + } + ee->deleted = EINA_TRUE; if (ee->refcount > 0) return; @@ -3494,7 +3502,7 @@ _ecore_evas_free(Ecore_Evas *ee) ee->prop.wm_rot.manual_mode.timer = NULL; eina_hash_free(ee->prop.cursors); ee->prop.cursors = NULL; - evas_free(ee->evas); + if (!ee->evas_dying) evas_free(ee->evas); ee->evas = NULL; ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE); ee->driver = NULL; @@ -5264,6 +5272,15 @@ ecore_evas_evas_new(Ecore_Evas *ee, int w, int h) return e; } +static void +_ecore_evas_event_del(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Ecore_Evas *ee = data; + + ee->evas_dying = EINA_TRUE; + ecore_evas_free(ee); +} + EAPI void ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window) { @@ -5277,6 +5294,9 @@ ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window) if (single_window) evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + + efl_event_callback_add(ee->evas, EFL_EVENT_INVALIDATE, _ecore_evas_event_del, ee); + ee->self_del = EINA_TRUE; } static Ecore_Animator * diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index cfbb367e2b..e8db23b99e 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -385,6 +385,8 @@ struct _Ecore_Evas unsigned char animator_ticked : 1; unsigned char animator_ran : 1; unsigned char first_frame : 1; + unsigned char self_del : 1; + unsigned char evas_dying : 1; }; struct _Ecore_Evas_Aux_Hint