Eo add ref: Fix a bug causing leaks and wrong refcount in some cases.

When using eo_add_ref, it was increasing the refcount before the user
context in the addition has fully ended. This means the object had its
reference increased while still not finalized, which means it was
sometimes passed with an increased refcount to unsuspecting class code.
The correct behaviour is to increase the reference count just before
returning the object to the user at the end of eo_add so the reference
count is only increased for whoever asked for it.

Breaks ABI!

@fix
This commit is contained in:
Tom Hacohen 2016-07-12 10:34:54 +01:00
parent a5eb66edd4
commit fdc0eef770
2 changed files with 10 additions and 10 deletions

View File

@ -649,7 +649,7 @@ EAPI Eina_Bool _eo_call_resolve(Eo *obj, const char *func_name, Eo_Op_Call_Data
EAPI void _eo_call_end(Eo_Op_Call_Data *call);
// end of the eo_add. Calls finalize among others
EAPI Eo * _eo_add_end(Eo *obj, Eina_Bool is_fallback);
EAPI Eo * _eo_add_end(Eo *obj, Eina_Bool is_ref, Eina_Bool is_fallback);
EAPI Eo *eo_super(const Eo *obj, const Eo_Class *cur_klass);
@ -675,7 +675,7 @@ EAPI Eo *_eo_self_get(void);
({ \
Eo * const __eo_self = _eo_add_internal_start(__FILE__, __LINE__, klass, parent, is_ref, EINA_FALSE); \
(void) ((void)0, ##__VA_ARGS__); \
(Eo *) _eo_add_end(eo_self, EINA_FALSE); \
(Eo *) _eo_add_end(eo_self, is_ref, EINA_FALSE); \
})
#else
@ -686,7 +686,7 @@ EAPI Eo *_eo_self_get(void);
( \
_eo_add_internal_start(__FILE__, __LINE__, klass, parent, is_ref, EINA_TRUE), \
##__VA_ARGS__, \
(Eo *) _eo_add_end(eo_self, EINA_TRUE) \
(Eo *) _eo_add_end(eo_self, is_ref, EINA_TRUE) \
)
#endif

View File

@ -649,7 +649,7 @@ _eo_class_funcs_set(Eo_Vtable *vtable, const Eo_Ops *ops, const _Eo_Class *hiera
}
EAPI Eo *
_eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback)
_eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo *parent_id, Eina_Bool ref EINA_UNUSED, Eina_Bool is_fallback)
{
_Eo_Object *obj;
Eo_Stack_Frame *fptr = NULL;
@ -724,11 +724,6 @@ _eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo
_eo_ref(new_obj);
}
if (ref && eo_parent_get(eo_id))
{
eo_ref(eo_id);
}
if (is_fallback)
{
fptr->obj = eo_id;
@ -780,11 +775,16 @@ cleanup:
}
EAPI Eo *
_eo_add_end(Eo *eo_id, Eina_Bool is_fallback)
_eo_add_end(Eo *eo_id, Eina_Bool is_ref, Eina_Bool is_fallback)
{
Eo *ret = eo_finalize(eo_id);
ret = _eo_add_internal_end(eo_id, ret);
if (is_ref && eo_parent_get(eo_id))
{
eo_ref(eo_id);
}
if (is_fallback)
{
_eo_add_fallback_stack_pop();