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)

-- 


Reply via email to