Hi, I think your summary about the Gtk is not what you think - read the docs further https://developer.gnome.org/gtk3/stable/GtkWindow.html#gtk-window-new and you see that actually the trivial example leaks the reference - just like an efl_add_ref with no unref or del later. They are *not* returning a pointer where you can expect to lose ownership at some future time. Notice also they do not pass parents to the constructors.
In ObjC the basic construct is obj = [klass alloc] ... do things with obj ... [obj release] and they made this less cumbersome with obj = [[klass alloc] autorelease] ... do things with obj This provides a guarantee that the obj reference is alive for the current scope. I can find no examples where an object reference may or may not stay live and may or may not need released based on a variable passed to the constructor call... Wanting safety in our applications is not pedantry - anything less than scope guarantees is asking for trouble and we are just patching bad decisions. I have been told on so many occasions that none of this API is final - but now there is a chance to make things better but I am too late? Please make up your mind. Andrew On Fri, 22 Dec 2017 at 10:56 Carsten Haitzler <ras...@rasterman.com> wrote: > On Fri, 22 Dec 2017 10:10:48 +0000 Andrew Williams <a...@andywilliams.me> > said: > > > On Fri, 22 Dec 2017 at 09:59 Carsten Haitzler <ras...@rasterman.com> > wrote: > > > > > On Fri, 22 Dec 2017 09:43:20 +0000 Andrew Williams < > a...@andywilliams.me> > > > said: > > > > > > > Hi, > > > > > > > > I think that maybe I could have explained this a little better, let > me > > > step > > > > back from the implementation details for a minute. > > > > > > > > As a user of this API all I want to know is do I have to unref a > > > reference > > > > that I have been handed. From this point of view we should be > consistent. > > > > My proposal was (intended) to mean that efl_add should never require > the > > > > user to unreference whereas efl_add_ref should always require this > (but > > > > only once - that may have been a bug). > > > > > > > > Having to know the value of the second parameter to the method to > > > ascertain > > > > the correct behaviour is what I think is confusing and should be > > > > eliminated. Therefore the main purpose was so that the docs could > ready > > > > simply "this is a borrowed reference which you should not unref" vs > "this > > > > is an owned reference and you must unref when done". > > > > > > yes. i got that. but your proposal is no better than what is there. in > fact > > > think it's worse. unless i didn't understand it? > > > > > > > "is no better"? it ensures that you know to unref efl_add_ref and that > you > > cannot accidentally use a risky efl_add. Not ideal which is why I > suggested > > efl_add_scope in a follow up which is something you don't have to unref > but > > also guarantees liveness for the scope. > > forcing all this code that builds widgets (see below about leaks) to > remember > to unref is asking for disaster as people will juyst end up using > efl_Add_ref > all the time because not doing so it incredibly inconvenient. it's also > going to > be a major complaint in usage. > > reality is ... people seem fine with how we do it in c. why? this is how > gtk > works... same thing. it's also how efl has worked for a long time. hello > world > for gtk: > > https://developer.gnome.org/gtk-tutorial/2.90/c39.html > https://developer.gnome.org/gtk3/stable/gtk-getting-started.html > > the construction return an object ptr, you do things with it, hand it to a > parent. no unreffing. in gtk the parent could delete the children any time > it > liked like in efl. this is a common design pattern already in c for this > kind > of stuff. > > you can be pedantic, or you can just be practical. this is one of these > "we're > being practical" things rather than pedantic. if you want to write code > pedantically then efl_add_ref() is there - remember to unref when going > out of > scope or you'll have leaks. > > > > i get your point... as i said. but your proposal doesn't sound as if > it's > > > better. > > > > > > what MIGHT be better is to class objects into "can have a null parent" > and > > > "must have a non-null parent". the 1st case doesn't change. from now. > the > > > 2nd > > > case results in efl_add returning NULL (construction fails) if the > parent > > > is > > > null. that might be an improvement. > > > > > > > Why do I, as the user, have to care what the content of the parent > variable > > is? It was suggested to me that efl_add could require a parent and then > > would safely return the reference, but you still have the race condition > so > > I'm not convinced. > > see above. gtk and friends are full of this condition yet people are fine > with > it. people have been fine with this in efl for a long time. it's not a race > condition really. it's a lifecycle behavior definition. once you hand a > child > to a parent, that parent can and will control lifecycle and thus it MAY > delete > it at some point... and that point MAY be immediately in some rare cases. > we > have a single efl_add() constructor do a multi-step "create, set > properties/callbcks and set parent etc. etc.". so yes - knowing what > parent is > matters because of this. > > > > > The added complication is the race condition with the "parent" usage > in > > > > efl_add. When I pass a parent reference to efl_add then the returned > > > handle > > > > is something I can use. Yes this is very helpful. But this is > dangerous. > > > We > > > > (as a framework) are providing 0 guarantee that the object will live > as > > > > long as the scope - that is entirely up to the parent, not the user > and > > > not > > > > the framework. This is also something that I think we should address. > > > > > > we can't guarantee it if the parent decides some time within the scope > to > > > delete the object you added. well we can;'t unless you use > efl_add_ref() > > > then > > > you create an object with 2 references (parent one and your scope/app > one) > > > and > > > you will have to remember to unref at end of scope. this leads to > verbose > > > code, > > > and having to remember to do this... which is more than likely going to > > > lead to > > > huge amounts of memory leaking. > > > > Only if not coded correctly. We currently return references which are not > > clear if they should be unref or not so there is not a huge difference. > > it is clear. if parent is NULL - YOU own (as the caller) the reference. > unref/del as appropriate. if parent is NOT NULL then parent owns the ref > and > the object lifecycle will be managed by the parent. what is not clear about > this? how is "well if you write it correctly and remember to add all the > unref's when exiting scope" better? it's MORE code and MORE places for > things > to go wrong. it's also not a common pattern in C. see the gtk samples and > legacy efl api too. > > > > so which is worse? sometimes a parent decides to delete an object on > you > > > while > > > you are still holding and using its handle, or that you always have to > > > unref > > > every obj you added when you exit scope? i'll take the first one any > day > > > of the > > > week. :) > > > > > > > I'm going to say safety. 100% safety is more important than removing a > line > > of code. This is our opportunity to do things right. Introducing a race > > condition at the root of our API seems an unfortunate choice. > > then you are free to use efl_add_ref(). reality is that 99.9% of the time > objects will not be deleted within scope where they are created and set up > because having this kind of behaviour is kind of nasty and it should be > avoided. we have safety thanks to eoid anyway. so you won't get a crash.. > you'll get an error print and things will recover just fine. because there > is > no automatic unreffing when exiting scope in C, requiring people to do > this by > hand is going to lead a world of leaks where people continue to forget > doing > this as this is not a rare thing but a common thing to do, and it's going > to > lead to more verbose code... in return for what? safety isn't improved. > eoid > took care of that already. > > this whole discussion was already had like 2+ years ago when the core > design > for eo was being hashed out. tom was like you wanting something > pedantically > correct requiring unrefs at end of scope etc. yes i know. the option of an > add > that doesn't return anything. that's kind of a very half-baked and not > useful > api. he ended up agreeing that what we have now is not perfect, but it's > the > best option for sanity. now we're having this discussion again and TBH i > think > it's a bit late. there is a mountain of code that now depends on this > design. > even if we were to choose to change - it'd be a nightmare to do and have > efl in > a horribly unstable state for weeks if not months. ever use where the > return is > used has to become an efl_add_ref, and those that done become efl_add so > every > instance needs inspection etc. and someone has to put the efl_unrefs in > all of > the scope exit points AND get it all right... > > this is the kind of change that would only really justify being done if we > had > a showstopper design bug. we do not. not IMHO. there is clear behaviour and > it's logical and simple. if you don't LIKE it... efl_add_ref is there for > you > to use and then to remember to unref on all scope exits by hand. i > certainly > would not choose to use this. > > > > > So there you go - the background behind my proposal. Hopefully if I > did > > > not > > > > explain the details well you can now see why I felt it is important. > > > > > > yup. i know the background. i'm speaking of the details of the > proposal. > > > > > > > Thanks, > > > > Andy > > > > > > > > On Fri, 22 Dec 2017 at 03:25 Carsten Haitzler <ras...@rasterman.com> > > > wrote: > > > > > > > > > On Thu, 21 Dec 2017 13:15:26 +0000 Andrew Williams < > > > a...@andywilliams.me> > > > > > said: > > > > > > > > > > > Hi, > > > > > > > > > > > > This is now well documented ( > > > > > > https://www.enlightenment.org/develop/tutorials/c/eo-refcount.md > ) > > > but > > > > > the > > > > > > more I use efl_add the more I feel it is confusing especially to > new > > > > > > developers. > > > > > > > > > > > > In the current model (if I understand it correctly) > > > > > > 1) child = efl_add(klass, parent) means the child must NOT be > > > > > unfeferenced > > > > > > 2) child = efl_add(klass, NULL) means the child should be > > > unreferenced > > > > > > 3) child = efl_add_ref(klass, parent) means the child must be > > > > > unreferenced > > > > > > 4) child = efl_add_ref(klass, NULL) somehow means that the child > > > should > > > > > be > > > > > > unreferenced twice > > > > > > > > > > #4 smells like a bug... 1 is intended. > > > > > > > > > > > In my opinion 1) and 4) are peculiar and so I provide a proposal > to > > > fix > > > > > > this: > > > > > > > > > > > > We could change efl_add to return void. It never retains a > > > reference. If > > > > > > the parent is NULL then it should be automatically unref before > > > > > returning. > > > > > > Then efl_add_ref would be changed to mirror this and always > retain > > > > > exactly > > > > > > 1 reference - so if parent is NULL there is no double count > returned. > > > > > > > > > > umm... then you are saying efl_add_ref() is exactly the same as > > > efl_add() > > > > > today. what does this help? and the shorter efl_add now returns > > > nothing so > > > > > i > > > > > can't use the return to usefully access the things i created later > on > > > like > > > > > add > > > > > callbacks to it, change the label of a button, delete a window, or > use > > > it > > > > > as a > > > > > parent for further adds which is like THE most common use case > around > > > when > > > > > building a ui for example (create box, then create a button and > pack > > > button > > > > > into box. i need the box to be able to do that). unless i use > > > efl_add_ref > > > > > which > > > > > si the same thing as efl_add now. > > > > > > > > > > > Using this model if an Eo * is returned then I know I have a > > > reference > > > > > and > > > > > > must later unref. > > > > > > Any need for using the pointer in an efl_add (which is no longer > > > > > returned) > > > > > > would still be supported through efl_added within the > constructor. > > > > > > > > > > if efl_add_ref returns an obj with only 1 reference, then this is > wrong > > > > > above. > > > > > if parent is NULL, yes you'd have to unref/del. if parent is not > null > > > then > > > > > there is still only 1 ref and it belongs to the parent object. so > > > > > > > > > > > What do people think about this? I put the suggestion forward to > > > improve > > > > > > the symettry with add and unref which is currently confusing. If > my > > > > > > assumptions above are incorrect please let me know! > > > > > > > > > > > > Thanks, > > > > > > Andy > > > > > > -- > > > > > > http://andywilliams.me > > > > > > http://ajwillia.ms > > > > > > > > > > > > > > > ------------------------------------------------------------------------------ > > > > > > Check out the vibrant tech community on one of the world's most > > > > > > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > > > > > > _______________________________________________ > > > > > > enlightenment-devel mailing list > > > > > > enlightenment-devel@lists.sourceforge.net > > > > > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > > > > > > > > > > > > > > > > > > > > > -- > > > > > ------------- Codito, ergo sum - "I code, therefore I am" > > > -------------- > > > > > Carsten Haitzler - ras...@rasterman.com > > > > > > > > > > -- > > > > http://andywilliams.me > > > > http://ajwillia.ms > > > > > > > > > -- > > > ------------- Codito, ergo sum - "I code, therefore I am" > -------------- > > > Carsten Haitzler - ras...@rasterman.com > > > > > > -- > > http://andywilliams.me > > http://ajwillia.ms > > > -- > ------------- Codito, ergo sum - "I code, therefore I am" -------------- > Carsten Haitzler - ras...@rasterman.com > > -- http://andywilliams.me http://ajwillia.ms ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel