forked from enlightenment/efl
eo: to avoid mistake in timing, efl_invalidate should always be triggered before any destructor code.
Differential Revision: https://phab.enlightenment.org/D6061
This commit is contained in:
parent
0090384ef5
commit
36f8a70041
|
@ -127,26 +127,31 @@ _efl_pending_futures_clear(Efl_Object_Data *pd)
|
|||
}
|
||||
}
|
||||
|
||||
// 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_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
|
||||
{
|
||||
efl_event_callback_call(obj, EFL_EVENT_INVALIDATE, NULL);
|
||||
Eina_Inlist *l;
|
||||
_Eo_Object *child;
|
||||
|
||||
efl_invalidate(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_object_invalidate(Eo *obj, Efl_Object_Data *pd)
|
||||
{
|
||||
_efl_pending_futures_clear(pd);
|
||||
|
||||
if (pd->invalidate) return ;
|
||||
efl_parent_set(obj, NULL);
|
||||
pd->invalidate = EINA_TRUE;
|
||||
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
|
||||
efl_parent_set(obj_id, NULL);
|
||||
|
||||
obj->invalidate = EINA_TRUE;
|
||||
|
||||
end:
|
||||
EO_OBJ_DONE(obj_id);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -658,10 +663,11 @@ _efl_object_parent_sink_set(Eo *obj, Eina_Bool sink)
|
|||
}
|
||||
|
||||
void
|
||||
_efl_object_reuse(Eo *obj)
|
||||
_efl_object_reuse(Eo *obj_id)
|
||||
{
|
||||
Efl_Object_Data *pd = efl_data_scope_get(obj, EFL_OBJECT_CLASS);
|
||||
pd->invalidate = EINA_FALSE;
|
||||
EO_OBJ_POINTER(obj_id, obj);
|
||||
obj->invalidate = EINA_FALSE;
|
||||
EO_OBJ_DONE(obj_id);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
|
@ -675,10 +681,10 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
|||
EO_OBJ_POINTER_GOTO(obj, eo_obj, err_impossible);
|
||||
|
||||
// Invalidated object can not be bring back to life
|
||||
if (pd->invalidate)
|
||||
if (eo_obj->invalidate)
|
||||
{
|
||||
ERR("Call of efl_parent_set(%p, %p) when object is already invalidated.\n", obj, parent_id);
|
||||
return ;
|
||||
goto err_impossible;
|
||||
}
|
||||
|
||||
if (pd->parent)
|
||||
|
@ -719,8 +725,8 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
|||
}
|
||||
else
|
||||
{
|
||||
pd->invalidate = EINA_TRUE;
|
||||
if (prev_parent) _efl_invalidate(obj);
|
||||
eo_obj->invalidate = EINA_TRUE;
|
||||
if (prev_parent) _efl_invalidate(eo_obj);
|
||||
|
||||
pd->parent = NULL;
|
||||
if (prev_parent && !eo_obj->del_triggered) efl_unref(obj);
|
||||
|
@ -758,15 +764,22 @@ _efl_object_finalized_get(const Eo *obj_id, Efl_Object_Data *pd EINA_UNUSED)
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_object_invalidated_get(const Eo *obj_id EINA_UNUSED, Efl_Object_Data *pd)
|
||||
_efl_object_invalidated_get(const Eo *obj_id, Efl_Object_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return pd->invalidate;
|
||||
Eina_Bool invalidate;
|
||||
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_TRUE);
|
||||
invalidate = obj->invalidate;
|
||||
EO_OBJ_DONE(obj_id);
|
||||
return invalidate;
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *klass)
|
||||
{
|
||||
if (pd->invalidate)
|
||||
Eina_Bool invalidate;
|
||||
|
||||
invalidate = _efl_object_invalidated_get((Eo*) obj, NULL);
|
||||
if (invalidate)
|
||||
{
|
||||
ERR("Calling efl_provider_find(%p) after the object was invalidated.", obj);
|
||||
return NULL;
|
||||
|
@ -2014,11 +2027,15 @@ efl_future_cb_from_desc(const Eo *o, const Efl_Future_Cb_Desc desc)
|
|||
Efl_Future_Pending *pending = NULL;
|
||||
Eina_Future **storage = NULL;
|
||||
Efl_Object_Data *pd;
|
||||
Eina_Bool invalidate;
|
||||
|
||||
EINA_SAFETY_ON_NULL_GOTO(o, end);
|
||||
pd = efl_data_scope_get(o, EFL_OBJECT_CLASS);
|
||||
EINA_SAFETY_ON_NULL_GOTO(pd, end);
|
||||
EINA_SAFETY_ON_TRUE_GOTO(pd->invalidate, end);
|
||||
EO_OBJ_POINTER_GOTO(o, eo_obj, end);
|
||||
invalidate = eo_obj->invalidate;
|
||||
EO_OBJ_DONE(o);
|
||||
EINA_SAFETY_ON_TRUE_GOTO(invalidate, end);
|
||||
pending = _efl_pending_future_new();
|
||||
EINA_SAFETY_ON_NULL_GOTO(pending, end);
|
||||
memcpy(&pending->desc, &desc, sizeof(Efl_Future_Cb_Desc));
|
||||
|
@ -2086,13 +2103,6 @@ _efl_object_destructor(Eo *obj, Efl_Object_Data *pd)
|
|||
|
||||
DBG("%p - %s.", obj, efl_class_name_get(obj));
|
||||
|
||||
// If the object has been invalidated yet, time to do it
|
||||
// This can happen when the object has no parent and get
|
||||
// deleted by efl_unref.
|
||||
if (!pd->invalidate)
|
||||
_efl_invalidate(obj);
|
||||
|
||||
|
||||
// special removal - remove from children list by hand after getting
|
||||
// child handle in case unparent method is overridden and does
|
||||
// extra things like removes other children too later on in the list
|
||||
|
|
|
@ -115,6 +115,7 @@ struct _Eo_Object
|
|||
Eina_Bool condtor_done:1;
|
||||
Eina_Bool finalized:1;
|
||||
Eina_Bool super:1;
|
||||
Eina_Bool invalidate:1;
|
||||
|
||||
Eina_Bool del_triggered:1;
|
||||
Eina_Bool destructed:1;
|
||||
|
@ -247,6 +248,24 @@ _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->invalidate) return;
|
||||
|
||||
id = _eo_obj_id_get(obj);
|
||||
|
||||
efl_event_callback_call(id, EFL_EVENT_INVALIDATE, NULL);
|
||||
|
||||
efl_invalidate(id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int line)
|
||||
{
|
||||
|
@ -255,6 +274,11 @@ _efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int
|
|||
|
||||
const _Efl_Class *klass = obj->klass;
|
||||
|
||||
// If the object has been invalidated yet, time to do it
|
||||
// before any destructor kick in. This can happen when
|
||||
// the object has no parent and get deleted by efl_unref.
|
||||
_efl_invalidate(obj);
|
||||
|
||||
efl_event_callback_call(_eo_obj_id_get(obj), EFL_EVENT_DEL, NULL);
|
||||
|
||||
_eo_condtor_reset(obj);
|
||||
|
|
Loading…
Reference in New Issue