cedric pushed a commit to branch master.

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

commit 83251edae77f9ae0c52edeb06512fbf0e2c39c8a
Author: Cedric Bail <ced...@osg.samsung.com>
Date:   Wed Mar 7 10:56:53 2018 -0800

    eo: introduce invalidate and noref state.
    
    This is just a first step. All user of destructor should be updated to
    move the code that rely on their efl_parent and on efl_provider_find to
    invalidate. Then we will be able to change the way efl_add and efl_del
    work to properly refcount things. efl_noref won't be triggered at the
    moment until both efl_parent_set(obj, NULL) and the last user ref are
    set to NULL. This is not what we want, but due to how user refcount is
    accounting parent at the moment, until all the code is move to rely
    on invalidate we can not fix this.
---
 src/lib/eo/efl_object.eo   | 20 +++++++++++++++++++-
 src/lib/eo/eo.c            |  1 +
 src/lib/eo/eo_base_class.c | 23 ++++++++++++++++++++++-
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/lib/eo/efl_object.eo b/src/lib/eo/efl_object.eo
index f41b6ee3eb..206d135524 100644
--- a/src/lib/eo/efl_object.eo
+++ b/src/lib/eo/efl_object.eo
@@ -130,6 +130,14 @@ abstract Efl.Object ()
             finalized: bool; [[$true if the object is finalized, $false 
otherwise]]
          }
       }
+      @property invalidated {
+         [[True if the object is already invalidated, otherwise false.]]
+         get {
+         }
+         values {
+            finalized: bool; [[$true if the object is invalidated, $false 
otherwise]]
+         }
+      }
       provider_find @const {
         [[Searches upwards in the object tree for a provider which knows the 
given class/interface.
 
@@ -155,13 +163,23 @@ abstract Efl.Object ()
       destructor {
          [[Call the object's destructor.
 
-           Should not be used with #eo_do. Only use it with #eo_do_super.
+           Should not be used with #efl_do. Only use it with #efl_do_super.
+          Will be triggered once #invalidate and #noref have been triggered.
          ]]
       }
       finalize {
          [[Called at the end of efl_add. Should not be called, just 
overridden.]]
          return: Efl.Object; [[The new object created, can be NULL if 
aborting]]
       }
+      invalidate {
+         [[Called when parent reference is lost/set to $NULL and switch the 
state of the object to invalidate.]]
+      }
+      noref {
+         [[Triggered when no reference are keeping the object alive.
+
+           The parent can be the last one keeping an object alive and so 
$noref can happen before $invalidate
+           as it is only impacted by the ref/unref of the object.]]
+      }
       name_find @const {
          [[Find a child object with the given name and return it.
 
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 8052fd714f..f2626acca5 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -1887,6 +1887,7 @@ efl_unref(const Eo *obj_id)
              EO_OBJ_DONE(obj_id);
              return;
           }
+        efl_noref((Eo *) obj_id);
         _efl_unref(obj);
      }
    EO_OBJ_DONE(obj_id);
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index f1eff91f3e..fe6da95b72 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -60,6 +60,7 @@ typedef struct
    Eina_Bool                  parent_sunk : 1; // If parent ref has already 
been settled (parent has been set, or we are in add_ref mode
    Eina_Bool                  allow_parent_unref : 1; // Allows unref to zero 
even with a parent
    Eina_Bool                  has_destroyed_event_cb : 1; // No proper count: 
minor optimization triggered at destruction only
+   Eina_Bool                  invalidate : 1; // Object become invalide once 
it loose its parent
 } Efl_Object_Data;
 
 typedef enum
@@ -620,6 +621,9 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo 
*parent_id)
        ((parent_id) && (!_eo_id_domain_compatible(parent_id, obj))))
      return;
 
+   // Invalidated object can not be bring back to life
+   if (pd->invalidate) return ;
+
    EO_OBJ_POINTER(obj, eo_obj);
    if (pd->parent)
      {
@@ -660,6 +664,7 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo 
*parent_id)
    else
      {
         pd->parent = NULL;
+        if (prev_parent) efl_invalidate(obj);
         if (prev_parent && !eo_obj->del_triggered) efl_unref(obj);
      }
 
@@ -694,6 +699,12 @@ _efl_object_finalized_get(Eo *obj_id, Efl_Object_Data *pd 
EINA_UNUSED)
    return finalized;
 }
 
+EOLIAN static Eina_Bool
+_efl_object_invalidated_get(Eo *obj_id EINA_UNUSED, Efl_Object_Data *pd)
+{
+   return pd->invalidate;
+}
+
 EOLIAN static Efl_Object *
 _efl_object_provider_find(const Eo *obj EINA_UNUSED, Efl_Object_Data *pd, 
const Efl_Object *klass)
 {
@@ -701,7 +712,6 @@ _efl_object_provider_find(const Eo *obj EINA_UNUSED, 
Efl_Object_Data *pd, const
    return NULL;
 }
 
-
 /* Children accessor */
 typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
 struct _Eo_Children_Iterator
@@ -2137,6 +2147,17 @@ _efl_object_finalize(Eo *obj, Efl_Object_Data *pd 
EINA_UNUSED)
    return obj;
 }
 
+static void
+_efl_object_invalidate(Eo *obj EINA_UNUSED, Efl_Object_Data *pd)
+{
+   pd->invalidate = EINA_TRUE;
+}
+
+static void
+_efl_object_noref(Eo *obj EINA_UNUSED, Efl_Object_Data *pd EINA_UNUSED)
+{
+}
+
 EOLIAN static void
 _efl_object_class_constructor(Efl_Class *klass EINA_UNUSED)
 {

-- 


Reply via email to