Eo add ref: Fix a bug causing leaks and wrong refcount in some cases.
authorTom Hacohen <tom@stosb.com>
Tue, 12 Jul 2016 09:34:54 +0000 (10:34 +0100)
committerTom Hacohen <tom@stosb.com>
Tue, 12 Jul 2016 10:09:40 +0000 (11:09 +0100)
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

src/lib/eo/Eo.h
src/lib/eo/eo.c

index ec14715..c8d050f 100644 (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
index 50b8e66..cb6776e 100644 (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();