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
|
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);
|
_efl_pending_futures_clear(pd);
|
||||||
|
|
||||||
if (pd->invalidate) return ;
|
EO_OBJ_POINTER(obj_id, obj);
|
||||||
efl_parent_set(obj, NULL);
|
if (obj->invalidate) goto end;
|
||||||
pd->invalidate = EINA_TRUE;
|
|
||||||
|
// 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
|
static void
|
||||||
|
@ -658,10 +663,11 @@ _efl_object_parent_sink_set(Eo *obj, Eina_Bool sink)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_efl_object_reuse(Eo *obj)
|
_efl_object_reuse(Eo *obj_id)
|
||||||
{
|
{
|
||||||
Efl_Object_Data *pd = efl_data_scope_get(obj, EFL_OBJECT_CLASS);
|
EO_OBJ_POINTER(obj_id, obj);
|
||||||
pd->invalidate = EINA_FALSE;
|
obj->invalidate = EINA_FALSE;
|
||||||
|
EO_OBJ_DONE(obj_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static void
|
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);
|
EO_OBJ_POINTER_GOTO(obj, eo_obj, err_impossible);
|
||||||
|
|
||||||
// Invalidated object can not be bring back to life
|
// 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);
|
ERR("Call of efl_parent_set(%p, %p) when object is already invalidated.\n", obj, parent_id);
|
||||||
return ;
|
goto err_impossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pd->parent)
|
if (pd->parent)
|
||||||
|
@ -719,8 +725,8 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pd->invalidate = EINA_TRUE;
|
eo_obj->invalidate = EINA_TRUE;
|
||||||
if (prev_parent) _efl_invalidate(obj);
|
if (prev_parent) _efl_invalidate(eo_obj);
|
||||||
|
|
||||||
pd->parent = NULL;
|
pd->parent = NULL;
|
||||||
if (prev_parent && !eo_obj->del_triggered) efl_unref(obj);
|
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
|
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 *
|
EOLIAN static Efl_Object *
|
||||||
_efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *klass)
|
_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);
|
ERR("Calling efl_provider_find(%p) after the object was invalidated.", obj);
|
||||||
return NULL;
|
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;
|
Efl_Future_Pending *pending = NULL;
|
||||||
Eina_Future **storage = NULL;
|
Eina_Future **storage = NULL;
|
||||||
Efl_Object_Data *pd;
|
Efl_Object_Data *pd;
|
||||||
|
Eina_Bool invalidate;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_GOTO(o, end);
|
EINA_SAFETY_ON_NULL_GOTO(o, end);
|
||||||
pd = efl_data_scope_get(o, EFL_OBJECT_CLASS);
|
pd = efl_data_scope_get(o, EFL_OBJECT_CLASS);
|
||||||
EINA_SAFETY_ON_NULL_GOTO(pd, end);
|
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();
|
pending = _efl_pending_future_new();
|
||||||
EINA_SAFETY_ON_NULL_GOTO(pending, end);
|
EINA_SAFETY_ON_NULL_GOTO(pending, end);
|
||||||
memcpy(&pending->desc, &desc, sizeof(Efl_Future_Cb_Desc));
|
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));
|
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
|
// special removal - remove from children list by hand after getting
|
||||||
// child handle in case unparent method is overridden and does
|
// child handle in case unparent method is overridden and does
|
||||||
// extra things like removes other children too later on in the list
|
// 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 condtor_done:1;
|
||||||
Eina_Bool finalized:1;
|
Eina_Bool finalized:1;
|
||||||
Eina_Bool super:1;
|
Eina_Bool super:1;
|
||||||
|
Eina_Bool invalidate:1;
|
||||||
|
|
||||||
Eina_Bool del_triggered:1;
|
Eina_Bool del_triggered:1;
|
||||||
Eina_Bool destructed:1;
|
Eina_Bool destructed:1;
|
||||||
|
@ -247,6 +248,24 @@ _eo_condtor_reset(_Eo_Object *obj)
|
||||||
obj->condtor_done = EINA_FALSE;
|
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
|
static inline void
|
||||||
_efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int line)
|
_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;
|
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);
|
efl_event_callback_call(_eo_obj_id_get(obj), EFL_EVENT_DEL, NULL);
|
||||||
|
|
||||||
_eo_condtor_reset(obj);
|
_eo_condtor_reset(obj);
|
||||||
|
|
Loading…
Reference in New Issue