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
This commit is contained in:
Carsten Haitzler 2016-08-10 00:30:55 +09:00
parent 4f840c5feb
commit 606e865823
2 changed files with 36 additions and 9 deletions

View File

@ -75,18 +75,17 @@ _evas_layer_free(Evas_Layer *lay)
void
_evas_layer_flush_removes(Evas_Layer *lay)
{
if (lay->walking_objects) return;
while (lay->removes)
{
Evas_Object_Protected_Data *obj = lay->removes->data;
Evas_Object_Protected_Data *obj;
if (lay->walking_objects) return;
EINA_LIST_FREE(lay->removes, obj)
{
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)
{

View File

@ -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)