cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=d052f001bee68517af7e6d5fec47c2345fff33f2

commit d052f001bee68517af7e6d5fec47c2345fff33f2
Author: Cedric Bail <ced...@osg.samsung.com>
Date:   Wed May 9 20:07:01 2018 -0700

    eo: move destruction of the link with children to be always after 
invalidate.
---
 src/lib/eo/eo_base_class.c | 51 +++++++++++++++++++++++++++++++++++++---------
 src/lib/eo/eo_private.h    | 20 +-----------------
 2 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index 3baff35724..d3c7619c26 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -132,21 +132,11 @@ _efl_pending_futures_clear(Efl_Object_Data *pd)
 static void
 _efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
 {
-   Eina_Inlist *l;
-   _Eo_Object *child;
-
    _efl_pending_futures_clear(pd);
 
    EO_OBJ_POINTER(obj_id, obj);
    if (obj->invalidate) goto end;
 
-   // Invalidate all children too
-   EINA_INLIST_FOREACH_SAFE(pd->children, l, child)
-     {
-        Eo *child_id = _eo_obj_id_get(child);
-        efl_parent_set(child_id, NULL);
-     }
-
    // Finally invalidate itself if it wasn't done already
    // I am not sure this is a good idea, but it force the
    // behavior of calling directly efl_invalidate to be the
@@ -160,6 +150,47 @@ _efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
    EO_OBJ_DONE(obj_id);
 }
 
+// Generate the invalidate event in all case and make sure it happens
+// before any user code can change the children invalidate state. This
+// make sure that the entire tree of object is valid at the time of
+// the invalidate event.
+void
+_efl_invalidate(_Eo_Object *obj)
+{
+   Eina_Array stash = { 0 };
+   Efl_Object_Data *pd;
+   _Eo_Object *child;
+   Eo *id;
+
+   if (obj->is_invalidating) return ;
+   obj->is_invalidating = EINA_TRUE;
+   if (obj->invalidate) return;
+
+   id = _eo_obj_id_get(obj);
+
+   efl_event_callback_call(id, EFL_EVENT_INVALIDATE, NULL);
+
+   pd = efl_data_scope_get(id, EFL_OBJECT_CLASS);
+
+   efl_invalidate(id);
+
+   eina_array_step_set(&stash, sizeof (stash), 4);
+
+   // Invalidate all children too
+   EINA_INLIST_FOREACH(pd->children, child)
+     eina_array_push(&stash, _efl_ref(child));
+
+   while ((child = eina_array_pop(&stash)))
+     {
+        Eo *child_id = _eo_obj_id_get(child);
+
+        efl_parent_set(child_id, NULL);
+        _efl_unref(child);
+     }
+
+   eina_array_flush(&stash);
+}
+
 static void
 _efl_object_noref(Eo *obj EINA_UNUSED, Efl_Object_Data *pd EINA_UNUSED)
 {
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index 96e7b7fee0..6302eeeafe 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -251,25 +251,7 @@ _eo_condtor_reset(_Eo_Object *obj)
    obj->condtor_done = EINA_FALSE;
 }
 
-// Generate the invalidate event in all case and make sure it happens
-// before any user code can change the children invalidate state. This
-// make sure that the entire tree of object is valid at the time of
-// the invalidate event.
-static void
-_efl_invalidate(_Eo_Object *obj)
-{
-   Eo *id;
-
-   if (obj->is_invalidating) return ;
-   obj->is_invalidating = EINA_TRUE;
-   if (obj->invalidate) return;
-
-   id = _eo_obj_id_get(obj);
-
-   efl_event_callback_call(id, EFL_EVENT_INVALIDATE, NULL);
-
-   efl_invalidate(id);
-}
+void _efl_invalidate(_Eo_Object *obj);
 
 static inline void
 _efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, 
int line)

-- 


Reply via email to