On Thu, Aug 20, 2015 at 9:22 AM, Daniel Zaoui <daniel.za...@samsung.com> wrote:
> On Thu, 20 Aug 2015 15:48:23 +0900
> Carsten Haitzler <ras...@rasterman.com> (The Rasterman) wrote:
>
>> On Thu, 20 Aug 2015 09:09:44 +0300 Daniel Zaoui
>> <daniel.za...@samsung.com> said:
>>
>> > Hi,
>> >
>> > On Wed, 19 Aug 2015 20:53:53 -0700
>> > Carsten Haitzler <ras...@rasterman.com> wrote:
>> >
>> > > raster pushed a commit to branch master.
>> > >
>> > > http://git.enlightenment.org/core/efl.git/commit/?id=8689d54471aafdd7a5b5a27ce116bf2ab68c1042
>> > >
>> > > commit 8689d54471aafdd7a5b5a27ce116bf2ab68c1042
>> > > Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
>> > > Date:   Thu Aug 20 12:50:52 2015 +0900
>> > >
>> > >     eo - destruction - ensure child is removed from parent child
>> > > list
>> > >     this follows on from cbc1a217bfc8b5c6dd94f0448f19245c43eb05e0
>> > > as this code was correct, but was then causing bugs due to
>> > > children staying in their parent lists. this should never have
>> > > happened and this is really bad. this fixes this and ensures
>> > > children on destruction are gone from their parent lists.
>> > >
>> > >     @fix
>> > > ---
>> > >  src/lib/eo/eo_base_class.c | 14 ++++++++++----
>> > >  1 file changed, 10 insertions(+), 4 deletions(-)
>> > >
>> > > diff --git a/src/lib/eo/eo_base_class.c
>> > > b/src/lib/eo/eo_base_class.c index fe52203..9f8252b 100644
>> > > --- a/src/lib/eo/eo_base_class.c
>> > > +++ b/src/lib/eo/eo_base_class.c
>> > > @@ -977,7 +977,6 @@ EOLIAN static void
>> > >  _eo_base_destructor(Eo *obj, Eo_Base_Data *pd)
>> > >  {
>> > >     Eo *child;
>> > > -   Eo_Base_Data *child_pd;
>> > >
>> > >     DBG("%p - %s.", obj, eo_class_name_get(MY_CLASS));
>> > >
>> > > @@ -987,11 +986,18 @@ _eo_base_destructor(Eo *obj, Eo_Base_Data
>> > > *pd) while (pd->children)
>> > >       {
>> > >          child = eina_list_data_get(pd->children);
>> > > -        child_pd = eo_data_scope_get(child, EO_BASE_CLASS);
>> > > -        pd->children = eina_list_remove_list(pd->children,
>> > > pd->children);
>> > > -        child_pd->parent_list = NULL;
>> > >          eo_do(child, eo_parent_set(NULL));
>> > >       }
>> > > +   // remove child from its parent on destruction - ha to be done
>> > > +   if (pd->parent)
>> > > +     {
>> > > +        Eo_Base_Data *parent_pd;
>> > > +
>> > > +        parent_pd = eo_data_scope_get(pd->parent, EO_BASE_CLASS);
>> > > +        parent_pd->children =
>> > > eina_list_remove_list(parent_pd->children,
>> > > +
>> > > pd->parent_list);
>> > > +        pd->parent_list = NULL;
>> > > +     }
>> > >
>> > >     _eo_generic_data_del_all(pd);
>> > >     _wref_destruct(pd);
>> > >
>> >
>> > The parent should never be !NULL when reaching the destructor. Imo,
>> > this code has not to be here. Instead, an error message should be
>> > displayed in the case the parent is still connected to the object.
>> > There is a bug but definitely the solution doesn't have to be here.
>> > I think this issue may happen if eo_del is never called and
>> > eo_unref is called instead. We need to check inside _eo_unref that
>> > the parent is NULL and display an error message.
>> >
>> > Tom, any thoughts?
>>
>> eo_suite simple examples show this case. in fact i think the test
>> case is broken too... but as such i followed the code, and read it.
>> if you destruct a child, the parent still has a list entry pointing
>> to it.
>>
>> _eo_unref() gets to 0, and _eo_del_internal() calls the destructor...
>
> eo_del unparents it and that's the issue of the test, as it is not called 
> before destruction. I think the test has not been adapted when references 
> mechanism has changed.
> Anyway, eo_unref should display an error message indicating that only one ref 
> exists and belongs to the parent. I think it should force unparenting too.

Maybe their is an issue in the test, but I have seen other issue where
when you do del with ref > 1 and then unref it doesn't remove the
parent. My believe is that the issue is somewhere in unref.

>> this does nothing in the way of removing from a parent (read it). the
>> base class destructor is the only place to do this... and so i added
>> it.
>>
>> look at
>>
>> START_TEST(eo_refs)
>>
>> here:
>>
>>    obj = eo_add(SIMPLE_CLASS, NULL);
>>    obj2 = eo_add(SIMPLE_CLASS, obj);
>>    eo_unref(obj2);
>>    eo_ref(obj2);
>>    eo_del(obj2);
>>    eo_unref(obj);
>
> I don't see how this test is supposed to work. eo_ref and eo_del should not 
> work well as the object is already deleted. As I said, it doesn't seem 
> updated with last Eo changes.
>
>>
>> we create obj, then obj2 as a child of obj, then unref obj2. after
>> this unref of obj2, obj2 was still in the child list of obj. this
>> isn't a complex case. its an insanely simple one. our own test cases
>> never caught this issue until i "fixed" the code above that pointed
>> this out. the base class destructor never removes an object from its
>> parent list. no code in the destructor to do that at all. i fixed
>> that :)
>
> The code is not supposed to be in the destructor as everything should have 
> been done before to not have a parent at this time. That's why I say the fix 
> should not be there imo but more in _eo_unref.

The code here create a problem for me. It doesn't call eo_parent_set
-> doesn't trigger the virtual function -> more impossible to fix leak
somewhere else. If we can't make parent_set work in a reliable way as
an eo function, then it is meaningless for it to be an eo function.

Cedric

------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to