summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hacohen <tom@stosb.com>2016-05-24 19:14:59 +0100
committerTom Hacohen <tom@stosb.com>2016-05-24 19:27:47 +0100
commit9c264fa0288a463f0587e2423c04c8b1403f264c (patch)
tree494396242c0fedc1fb850e480e1025096b5fc5d3
parent4bae0f135a9bb9fa57f8a5cd3ee42ace049d893d (diff)
Eo: Fix issue of too many unrefs in some cases.
This problem was that because the refcount is now shared between the parent and the programmer in some cases we would get a double unref. An example way of triggering it is creating a button and putting it in a box. The box has a callback registered that when the button is deleted it would delete itself too. The problem is that the delete callback is called the button is removed from the box thus causing the box to unref it again (because of the parent), although the refcount was already accounted for. There is another more convoluted scenario that I have yet to fix. Thanks to raster for reporting.
-rw-r--r--src/lib/eo/eo_base_class.c7
-rw-r--r--src/lib/eo/eo_private.h2
2 files changed, 3 insertions, 6 deletions
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index fa5222d888..1743695019 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -488,8 +488,9 @@ _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id)
488 pd->parent, obj); 488 pd->parent, obj);
489 } 489 }
490 490
491 /* Only unref if we don't have a new parent instead. */ 491 /* Only unref if we don't have a new parent instead and we are not at
492 if (!parent_id) 492 * the process of deleting the object.*/
493 if (!parent_id && !eo_obj->del_triggered)
493 { 494 {
494 _eo_unref(eo_obj); 495 _eo_unref(eo_obj);
495 } 496 }
@@ -1432,8 +1433,6 @@ _eo_base_destructor(Eo *obj, Eo_Base_Data *pd)
1432 1433
1433 if (pd->parent) 1434 if (pd->parent)
1434 { 1435 {
1435 /* A bit ugly, but unparent unrefs, so we need to ref before. */
1436 eo_ref(obj);
1437 eo_parent_set(obj, NULL); 1436 eo_parent_set(obj, NULL);
1438 } 1437 }
1439 1438
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index dd5176cb2e..3cba394896 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -332,8 +332,6 @@ _eo_unref(_Eo_Object *obj)
332 obj->del_triggered = EINA_TRUE; 332 obj->del_triggered = EINA_TRUE;
333 333
334 _eo_del_internal(__FILE__, __LINE__, obj); 334 _eo_del_internal(__FILE__, __LINE__, obj);
335
336 obj->del_triggered = EINA_FALSE;
337#ifdef EO_DEBUG 335#ifdef EO_DEBUG
338 /* If for some reason it's not empty, clear it. */ 336 /* If for some reason it's not empty, clear it. */
339 while (obj->xrefs) 337 while (obj->xrefs)