raster pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=606e865823ef2d7e1b1cab6e4720a6c173cfae7f
commit 606e865823ef2d7e1b1cab6e4720a6c173cfae7f Author: Carsten Haitzler (Rasterman) <[email protected]> Date: Wed Aug 10 00:30:55 2016 +0900 evas smart obj delete on shutdown - fix weird child with null parent while removing children from a parent smart object, the destruction of the smart obj encountered childrne with NULL parents. they were in the child list but had no parent. This was totally odd and unexpected, thus caused an infinite loop trying to dlete a child that won't be removed from the list because parent is NULL thus it cna't find the parent list to remove it from. This works around that and then complains with an error. The workaround also seems to have encountered what might be a compiler bug so I prepended to the layer object list rather than appended. this at leats stops the hang. @fix --- src/lib/evas/canvas/evas_layer.c | 9 ++++----- src/lib/evas/canvas/evas_object_smart.c | 34 ++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/lib/evas/canvas/evas_layer.c b/src/lib/evas/canvas/evas_layer.c index b81c0e0..bee7449 100644 --- a/src/lib/evas/canvas/evas_layer.c +++ b/src/lib/evas/canvas/evas_layer.c @@ -75,18 +75,17 @@ _evas_layer_free(Evas_Layer *lay) void _evas_layer_flush_removes(Evas_Layer *lay) { + Evas_Object_Protected_Data *obj; + if (lay->walking_objects) return; - while (lay->removes) + EINA_LIST_FREE(lay->removes, obj) { - Evas_Object_Protected_Data *obj = lay->removes->data; - lay->objects = (Evas_Object_Protected_Data *) eina_inlist_remove(EINA_INLIST_GET(lay->objects), EINA_INLIST_GET(obj)); - lay->removes = eina_list_remove_list(lay->removes, lay->removes); obj->layer = NULL; obj->in_layer = 0; - lay->usage--; + if (lay->usage > 0) lay->usage--; } if (lay->usage <= 0) { diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 40c3ac2..a189101 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -298,7 +298,6 @@ evas_object_smart_member_del(Evas_Object *eo_obj) if (!obj) return; if (!obj->smart.parent) return; Evas_Object *smart_obj = obj->smart.parent; - efl_canvas_group_member_del(smart_obj, eo_obj); } @@ -1270,8 +1269,37 @@ evas_object_smart_cleanup(Evas_Object *eo_obj) while (o->contained) { - Evas_Object *contained_obj = ((Evas_Object_Protected_Data *)o->contained)->object; - evas_object_smart_member_del(contained_obj); + Evas_Object_Protected_Data *contained = + (Evas_Object_Protected_Data *)o->contained; + Evas_Object *contained_obj = contained->object; + + if (contained->smart.parent != eo_obj) + { + Evas_Layer *lay = obj->layer; + + ERR("This is bad - object %p in child list for %p has parent %p", contained_obj, eo_obj, contained->smart.parent); + o->contained = eina_inlist_remove + (o->contained, EINA_INLIST_GET(contained)); + if (lay) + { + // this SHOULD be eina_inlist_append() BUT seemingly + // if we call this this objetc gets magicaly added + // back to o->conmtaind above NOt lay->objects. this + // is utterly bizzarre and the only explanation i + // can come up with right now is a compiler bug. + lay->objects = (Evas_Object_Protected_Data *) + eina_inlist_prepend(EINA_INLIST_GET(lay->objects), + EINA_INLIST_GET(contained)); + if (contained->layer != lay) + { + if (contained->layer) contained->layer->usage--; + contained->layer = lay; + contained->in_layer = 1; + lay->usage++; + } + } + } + else evas_object_smart_member_del(contained_obj); } while (o->callbacks) --
