From: Enlightenment S. <no-...@en...> - 2012-11-24 04:22:28
|
Log: delay e_win and e_popup deletes to avoid bad mem accesses from objects/callbacks that free evases deep inside a callback tree. :) Author: raster Date: 2012-11-23 20:22:21 -0800 (Fri, 23 Nov 2012) New Revision: 79622 Trac: http://trac.enlightenment.org/e/changeset/79622 Modified: trunk/e/src/bin/e_object.c trunk/e/src/bin/e_object.h trunk/e/src/bin/e_popup.c trunk/e/src/bin/e_win.c Modified: trunk/e/src/bin/e_object.c =================================================================== --- trunk/e/src/bin/e_object.c 2012-11-24 02:32:59 UTC (rev 79621) +++ trunk/e/src/bin/e_object.c 2012-11-24 04:22:21 UTC (rev 79622) @@ -26,17 +26,43 @@ return obj; } +static void +_delay_del(void *data) +{ + E_Object *obj = data; + + obj->delay_del_job = NULL; + if (obj->del_att_func) obj->del_att_func(obj); + if (obj->del_func) obj->del_func(obj); + e_object_unref(obj); +} + EAPI void e_object_del(E_Object *obj) { E_OBJECT_CHECK(obj); if (obj->deleted) return; + if (obj->del_delay_func) + { + obj->del_delay_func(obj); + if (!obj->delay_del_job) + obj->delay_del_job = ecore_job_add(_delay_del, obj); + obj->deleted = 1; + return; + } obj->deleted = 1; if (obj->del_att_func) obj->del_att_func(obj); if (obj->del_func) obj->del_func(obj); e_object_unref(obj); } +EAPI void +e_object_delay_del_set(E_Object *obj, void *func) +{ + E_OBJECT_CHECK(obj); + obj->del_delay_func = func; +} + EAPI int e_object_is_del(E_Object *obj) { Modified: trunk/e/src/bin/e_object.h =================================================================== --- trunk/e/src/bin/e_object.h 2012-11-24 02:32:59 UTC (rev 79621) +++ trunk/e/src/bin/e_object.h 2012-11-24 04:22:21 UTC (rev 79622) @@ -63,8 +63,10 @@ E_Object_Cleanup_Func cleanup_func; E_Object_Cleanup_Func free_att_func; E_Object_Cleanup_Func del_att_func; + E_Object_Cleanup_Func del_delay_func; Eina_Inlist *del_fn_list; void *data; + Ecore_Job *delay_del_job; int walking_list; Eina_Bool deleted : 1; }; @@ -80,6 +82,7 @@ EAPI void *e_object_alloc (int size, int type, E_Object_Cleanup_Func cleanup_func); EAPI void e_object_del (E_Object *obj); +EAPI void e_object_delay_del_set (E_Object *obj, void *func); EAPI int e_object_is_del (E_Object *obj); EAPI void e_object_del_func_set (E_Object *obj, E_Object_Cleanup_Func del_func); EAPI void e_object_type_set (E_Object *obj, int type); Modified: trunk/e/src/bin/e_popup.c =================================================================== --- trunk/e/src/bin/e_popup.c 2012-11-24 02:32:59 UTC (rev 79621) +++ trunk/e/src/bin/e_popup.c 2012-11-24 04:22:21 UTC (rev 79622) @@ -41,6 +41,7 @@ pop = E_OBJECT_ALLOC(E_Popup, E_POPUP_TYPE, _e_popup_free); if (!pop) return NULL; + e_object_delay_del_set(E_OBJECT(pop), e_popup_hide); pop->zone = zone; pop->zx = pop->zone->x; pop->zy = pop->zone->y; Modified: trunk/e/src/bin/e_win.c =================================================================== --- trunk/e/src/bin/e_win.c 2012-11-24 02:32:59 UTC (rev 79621) +++ trunk/e/src/bin/e_win.c 2012-11-24 04:22:21 UTC (rev 79622) @@ -215,6 +215,7 @@ win = E_OBJECT_ALLOC(E_Win, E_WIN_TYPE, _e_win_free); if (!win) return NULL; e_object_del_func_set(E_OBJECT(win), _e_win_del); + e_object_delay_del_set(E_OBJECT(win), e_win_hide); win->container = con; win->ecore_evas = e_canvas_new(con->manager->root, 0, 0, 1, 1, 1, 0, |