cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=224049fa18bc84d375df3be93435fb1235990c13
commit 224049fa18bc84d375df3be93435fb1235990c13 Author: Cedric Bail <[email protected]> Date: Mon Apr 2 17:18:46 2018 -0700 eo: trigger invalidate and noref event before any modification is commited on the object tree. --- src/lib/eo/eo.c | 9 +++++- src/lib/eo/eo_base_class.c | 70 ++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 0fb5891d33..479938a44a 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1882,6 +1882,14 @@ efl_unref(const Eo *obj_id) { EO_OBJ_POINTER_RETURN(obj_id, obj); + if (EINA_UNLIKELY(obj->user_refcount == 1)) + { + // The noref event should happen before any object in the + // tree get affected by the change in refcount. + efl_event_callback_call((Eo *) obj_id, EFL_EVENT_NOREF, NULL); + efl_noref((Eo *) obj_id); + } + --(obj->user_refcount); #ifdef EO_DEBUG _eo_log_obj_ref_op(obj, EO_REF_OP_UNREF); @@ -1896,7 +1904,6 @@ 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 4dfde15370..fefc1060a8 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -110,6 +110,43 @@ typedef struct static int _eo_nostep_alloc = -1; +static void +_efl_pending_futures_clear(Efl_Object_Data *pd) +{ + while (pd->pending_futures) + { + Efl_Future_Pending *pending = EINA_INLIST_CONTAINER_GET(pd->pending_futures, Efl_Future_Pending); + Eina_Future *future = *pending->desc.storage; + assert(future); + eina_future_cancel(future); + } +} + +// 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 *obj) +{ + efl_event_callback_call(obj, EFL_EVENT_INVALIDATE, NULL); + + efl_invalidate(obj); +} + +static void +_efl_object_invalidate(Eo *obj, Efl_Object_Data *pd) +{ + _efl_pending_futures_clear(pd); + efl_parent_set(obj, NULL); + pd->invalidate = EINA_TRUE; +} + +static void +_efl_object_noref(Eo *obj EINA_UNUSED, Efl_Object_Data *pd EINA_UNUSED) +{ +} + static inline void _efl_object_extension_free(Efl_Object_Extension *ext) { @@ -676,7 +713,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) _efl_invalidate(obj); if (prev_parent && !eo_obj->del_triggered) efl_unref(obj); } @@ -1934,18 +1971,6 @@ EAPI const Eina_Value_Type *EFL_DBG_INFO_TYPE = &_EFL_DBG_INFO_TYPE; /* EFL_OBJECT_CLASS stuff */ #define MY_CLASS EFL_OBJECT_CLASS -static void -_efl_pending_futures_clear(Efl_Object_Data *pd) -{ - while (pd->pending_futures) - { - Efl_Future_Pending *pending = EINA_INLIST_CONTAINER_GET(pd->pending_futures, Efl_Future_Pending); - Eina_Future *future = *pending->desc.storage; - assert(future); - eina_future_cancel(future); - } -} - static Eina_Value _efl_future_cb(void *data, const Eina_Value value, const Eina_Future *dead_future) { @@ -2056,7 +2081,8 @@ _efl_object_destructor(Eo *obj, Efl_Object_Data *pd) // This can happen when the object has no parent and get // deleted by efl_unref. if (!pd->invalidate) - efl_invalidate(obj); + _efl_invalidate(obj); + // special removal - remove from children list by hand after getting // child handle in case unparent method is overridden and does @@ -2170,22 +2196,6 @@ _efl_object_finalize(Eo *obj, Efl_Object_Data *pd EINA_UNUSED) return obj; } -static void -_efl_object_invalidate(Eo *obj, Efl_Object_Data *pd) -{ - efl_event_callback_call(obj, EFL_EVENT_INVALIDATE, NULL); - - _efl_pending_futures_clear(pd); - efl_parent_set(obj, NULL); - pd->invalidate = EINA_TRUE; -} - -static void -_efl_object_noref(Eo *obj, Efl_Object_Data *pd EINA_UNUSED) -{ - efl_event_callback_call(obj, EFL_EVENT_NOREF, NULL); -} - EOLIAN static void _efl_object_class_constructor(Efl_Class *klass EINA_UNUSED) { --
