forked from enlightenment/efl
eo: actually enforcing the efl_parent_set code path is necessary to enforce the predictability of the code path.
This commit is contained in:
parent
23e2c0bdb8
commit
e1d41eef3a
|
@ -43,7 +43,7 @@ typedef struct
|
|||
Eo ***wrefs;
|
||||
} Efl_Object_Extension;
|
||||
|
||||
typedef struct
|
||||
struct _Efl_Object_Data
|
||||
{
|
||||
Eina_Inlist *children;
|
||||
Eo *parent;
|
||||
|
@ -68,7 +68,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
|
||||
} Efl_Object_Data;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -135,7 +135,6 @@ _efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
|
|||
_efl_pending_futures_clear(pd);
|
||||
|
||||
EO_OBJ_POINTER(obj_id, obj);
|
||||
if (obj->invalidate) goto end;
|
||||
|
||||
// Finally invalidate itself if it wasn't done already
|
||||
// I am not sure this is a good idea, but it force the
|
||||
|
@ -144,9 +143,6 @@ _efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
|
|||
if (!obj->is_invalidating)
|
||||
efl_parent_set(obj_id, NULL);
|
||||
|
||||
obj->invalidate = EINA_TRUE;
|
||||
|
||||
end:
|
||||
EO_OBJ_DONE(obj_id);
|
||||
}
|
||||
|
||||
|
@ -189,6 +185,8 @@ _efl_invalidate(_Eo_Object *obj)
|
|||
}
|
||||
|
||||
eina_array_flush(&stash);
|
||||
|
||||
obj->invalidate = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -711,7 +709,7 @@ _efl_object_reuse(_Eo_Object *obj)
|
|||
obj->invalidate = EINA_FALSE;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
EOLIAN void
|
||||
_efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
||||
{
|
||||
Eo *prev_parent = pd->parent;
|
||||
|
|
|
@ -251,7 +251,9 @@ _eo_condtor_reset(_Eo_Object *obj)
|
|||
obj->condtor_done = EINA_FALSE;
|
||||
}
|
||||
|
||||
void _efl_invalidate(_Eo_Object *obj);
|
||||
typedef struct _Efl_Object_Data Efl_Object_Data;
|
||||
|
||||
EOLIAN void _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id);
|
||||
|
||||
static inline void
|
||||
_efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int line)
|
||||
|
@ -261,10 +263,27 @@ _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
|
||||
// If the object hasn't 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);
|
||||
if (obj->parent)
|
||||
{
|
||||
Eo *parent = efl_parent_get(_eo_obj_id_get(obj));
|
||||
|
||||
ERR("Destructor path being taken while object [%s] still has a parent [%s] in state %i:%i.",
|
||||
efl_debug_name_get(_eo_obj_id_get(obj)),
|
||||
efl_debug_name_get(parent),
|
||||
obj->is_invalidating, obj->invalidate);
|
||||
|
||||
efl_parent_set(_eo_obj_id_get(obj), NULL);
|
||||
|
||||
if (obj->parent)
|
||||
{
|
||||
CRI("Something is preventing [%s] from disconnecting from its parent, bypassing.",
|
||||
efl_debug_name_get(_eo_obj_id_get(obj)));
|
||||
_efl_object_parent_set(_eo_obj_id_get(obj), efl_data_scope_get(_eo_obj_id_get(obj), EFL_OBJECT_CLASS), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
efl_event_callback_call(_eo_obj_id_get(obj), EFL_EVENT_DEL, NULL);
|
||||
|
||||
|
|
Loading…
Reference in New Issue