forked from enlightenment/efl
Eo: Fix references of objects
This commit is contained in:
parent
6c8489c3b7
commit
25242e6af9
|
@ -850,9 +850,13 @@ _efl_add_end(Eo *eo_id, Eina_Bool is_ref, Eina_Bool is_fallback)
|
|||
Eo *ret = efl_finalize(eo_id);
|
||||
ret = _efl_add_internal_end(eo_id, ret);
|
||||
|
||||
if (is_ref && efl_parent_get(eo_id))
|
||||
if (is_ref)
|
||||
{
|
||||
efl_ref(eo_id);
|
||||
if (efl_parent_get(eo_id))
|
||||
{
|
||||
efl_ref(eo_id);
|
||||
}
|
||||
_efl_object_parent_sink(eo_id);
|
||||
}
|
||||
|
||||
if (is_fallback)
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef struct
|
|||
unsigned short event_freeze_count;
|
||||
Eina_Bool deletions_waiting : 1;
|
||||
Eina_Bool callback_stopped : 1;
|
||||
Eina_Bool parent_sunk : 1; // If parent ref has already been settled (parent has been set, or we are in add_ref mode
|
||||
} Efl_Object_Data;
|
||||
|
||||
typedef enum {
|
||||
|
@ -533,9 +534,17 @@ _efl_object_del(const Eo *obj, Efl_Object_Data *pd EINA_UNUSED)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
_efl_object_parent_sink(Eo *obj)
|
||||
{
|
||||
Efl_Object_Data *pd = efl_data_scope_get(obj, EFL_OBJECT_CLASS);
|
||||
pd->parent_sunk = EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
||||
{
|
||||
Eo *prev_parent = pd->parent;
|
||||
if ((pd->parent == parent_id) ||
|
||||
((parent_id) && (!_eo_id_domain_compatible(parent_id, obj))))
|
||||
return;
|
||||
|
@ -552,10 +561,6 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
|||
// this error is highly unlikely so move it out of the normal
|
||||
// instruction path to avoid l1 cache pollution
|
||||
else goto err_impossible;
|
||||
|
||||
/* Only unref if we don't have a new parent instead and we are not at
|
||||
* the process of deleting the object.*/
|
||||
if (!parent_id && !eo_obj->del_triggered) efl_unref(obj);
|
||||
}
|
||||
|
||||
/* Set new parent */
|
||||
|
@ -569,16 +574,23 @@ _efl_object_parent_set(Eo *obj, Efl_Object_Data *pd, Eo *parent_id)
|
|||
pd->parent = parent_id;
|
||||
parent_pd->children = eina_inlist_append(parent_pd->children,
|
||||
EINA_INLIST_GET(eo_obj));
|
||||
if (!prev_parent && pd->parent_sunk) efl_ref(obj);
|
||||
pd->parent_sunk = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pd->parent = NULL;
|
||||
if (prev_parent) efl_unref(obj);
|
||||
// unlikely this error happens, so move it out of execution path
|
||||
// to improve l1 cache efficiency
|
||||
goto err_parent;
|
||||
}
|
||||
}
|
||||
else pd->parent = NULL;
|
||||
else
|
||||
{
|
||||
pd->parent = NULL;
|
||||
if (prev_parent && !eo_obj->del_triggered) efl_unref(obj);
|
||||
}
|
||||
|
||||
EO_OBJ_DONE(obj);
|
||||
return;
|
||||
|
|
|
@ -196,6 +196,8 @@ typedef struct
|
|||
int line;
|
||||
} Eo_Xref_Node;
|
||||
|
||||
void _efl_object_parent_sink(Eo *obj);
|
||||
|
||||
static inline
|
||||
Eo *_eo_header_id_get(const Eo_Header *header)
|
||||
{
|
||||
|
|
|
@ -611,8 +611,8 @@ START_TEST(efl_refs)
|
|||
|
||||
efl_parent_set(obj2, obj);
|
||||
efl_parent_set(obj3, obj);
|
||||
ck_assert_int_eq(efl_ref_get(obj2), 1);
|
||||
ck_assert_int_eq(efl_ref_get(obj3), 1);
|
||||
ck_assert_int_eq(efl_ref_get(obj2), 2);
|
||||
ck_assert_int_eq(efl_ref_get(obj3), 2);
|
||||
|
||||
efl_del(obj);
|
||||
efl_del(obj2);
|
||||
|
|
Loading…
Reference in New Issue