Wow, I guess I walked into that with my "... whatever ..." so let's go 1 step simpler still:
void some_api(Eo *parent) { Eo *var = efl_add(SOME_CLASS, parent); printf("I got an Eo %p, %s\n", var, efl_name_get(var)); // TODO figure whether or not I should release var efl_unref(var); // ??? } This is still not clear as we don't know what parent was used. Compare to: void some_api(void) { char *ptr = malloc(10); printf("Got pointer %p\n", ptr); free(ptr); } Here it is clear. malloc always returns a memory handle that must be freed. Are you seeing the confusion yet? I don't think I have it in me to explain any further. What I really want to avoid is having people confused by our new API and having to review this again in retrospect a few years down the line. Andy On Wed, 3 Jan 2018 at 03:59 Carsten Haitzler <ras...@rasterman.com> wrote: > On Tue, 02 Jan 2018 19:19:37 +0000 Andrew Williams <a...@andywilliams.me> > said: > > > Hi, > > > > I am obviously struggling to explain this with words, so will try with > code. > > Take the following code fragment: > > > > void some_api(Eo *parent) { > > Eo *var = efl_add(SOME_CLASS, parent); > > > > ... do some stuff with var (possible, acknowledged, race condition) > ... > > > > // TODO figure whether or not I should release var > > efl_unref(var); // ??? > > } > > > > In that code how can I know the correct behaviour without inspecting the > > content of parent? > > the same as: > > void some_api(...) { > char *ptr = malloc(10); > ... > free(ptr); // ??? > } > > you do NOT know if you are to free or not ... it depends what you do with > ptr > between malloc and end of scope. do you pass the ptr to another func to > consume it or not?stick it in a list or array to store it? this is life in > C. C > is not java. > > parent here is an explicit store like a list or array. store this object in > this parent (if not null). it's explicit. > > > If I am a user of this API I would expect to be able to read code and > > understand if the correct objects have been released. > > With the last line this may be released too soon, without it we may have > a > > memory leak... > > reading your sample code says to me "this object REQUIRES a parent" > otherwise > why would you pass in a parent var at all? you'd use NULL if it doesn't. > > > Does that help? > > Andy > > > > On Wed, 27 Dec 2017 at 07:15 Carsten Haitzler <ras...@rasterman.com> > wrote: > > > > > On Tue, 26 Dec 2017 17:46:50 -0200 Felipe Magno de Almeida > > > <felipe.m.alme...@gmail.com> said: > > > > > > > JP, Cedric, me and TAsn have been having this argument for a while. > > > > > > > > IMO, the whole problem is that we're thinking of ownership in terms > > > > of parentship, which is wrong with reference counting. Ownership > > > > is shared between all reference owners and that's it. That's also > > > > the only sane way for bindings to work without having references > > > > being pull under their feet. > > > > > > > > The whole efl_del argument just exist because it is kinda poorly > > > > named. IMO, del means: get this object to an "empty" state. > > > > Just like close to files and hide and unparent to UI objects. efl_del > > > > should not steal references under people who owns it, the object > > > > would get deleted at a later time when everybody using the object > > > > stops doing so, we could even return errors from efl_del'eted > > > > objects for methods that do not make sense anymore, causing > > > > most actions to, possibly, halt earlier rather than later. > > > > > > > > IMO, the whole problem with efl_add/efl_add_ref is that > > > > "parents" are treated specially, which they should not. parent_set > > > > should increment efl_ref and parent_unset should decrement it. > > > > > > that's actually what happens, why efl_add_ref ends up with a refcount > of > > > 2, and > > > efl_add has a refcount of 1 (if parent is non-null). efl_add if parent > is > > > not > > > null is doing a parent_set during add. it's taking the "convenience" > that > > > the > > > parent is transferred from scope to parent just so you dont have to > unref > > > at > > > end of scope manually - in c that is. we're really just talking c here. > > > > > > > For C, OTH, where we do expect some "automatism" on resource > > > > handling, efl_unref'ing may be too much of a hassle when a > > > > parent is already going to handle the lifetime of the object. So, > > > > > > that was precisely the vote and discussion back in 2014. so while what > we > > > have > > > in c is not "strictly correct" (so to speak) it's far more convenient > than > > > forcing people to manually unref at end of scope. > > > > > > > it would make sense, IMO, for efl_add_scope. It could even be > > > > that efl_add_scope is named efl_add, no problem, as long as > > > > there's a efl_add that keeps this semantics for binding > > > > development. Which also means that parent_set/unset must > > > > be fixed. > > > > > > that'd be efl_add_ref() for bindings where scope is auto-managed by the > > > language (as above), and efl_add for c. if you want to write c in the > > > "strict > > > scope references" way like these other languages, then efl_add_ref is > > > there for > > > that. it's going to be inconvenient and requires you to handle scope > > > cleaning > > > correctly. with some gcc extensions this can actually be automated, > but the > > > problem is we have to have our api work without such extensions. > > > > > > you can use __attribute__ ((__cleanup__(efl_unref))) on such vars in > > > gcc... but > > > it's non-standard. if this was standard across all major compilers then > > > this > > > whole argument would be moot. we're have efl_add behave like > efl_add_ref > > > all > > > the time and require all objects handles to be unique in scope and have > > > some > > > macro to declare the object handle with the above attributes and you > have > > > to > > > compile with -fexceptions to handle c++ exception unwinding if it goes > > > through > > > some c code along the way.... but as i said. it's non-standard. we > can't > > > rely > > > on it. > > > > > > > Also, @own tags must _not_ relate to parent_set, because that > > > > has no useful information for tags or users, if needed we can > > > > add a @reparent tag, but that's not really special information > > > > such as real owernship information. > > > > > > > > So, #4 on the original OP should be treated as a bug if we > > > > consider efl_add as efl_add_scope, but we also need > > > > to fix parent_set/parent_unset. And code must not unref > > > > more than they ref. > > > > > > that was my take too. it should be unrefed only once. it smells of a > bug > > > to me. > > > i have very rarely played (i think just once or twice) with > efl_add_ref(). > > > i've > > > just use efl_ref() and efl_unref(). > > > > > > > Regards, > > > > > > > > > > > > On Tue, Dec 26, 2017 at 10:21 AM, Andrew Williams < > a...@andywilliams.me> > > > > wrote: > > > > > In the books I have read they consider null being a special case of > > > > > behaviour within a method just as confusing as passing a bool like > in > > > your > > > > > illustration. > > > > > > > > > > Andy > > > > > > > > > > On Tue, 26 Dec 2017 at 12:19, Andrew Williams < > a...@andywilliams.me> > > > wrote: > > > > > > > > > >> Hi, > > > > >> > > > > >> With the proposal of efl_add and efl_add_child we remove the need > for > > > > >> efl_add_ref* as the result of the former becomes consistent in its > > > return > > > > >> of owned or not owned references. > > > > >> Hopefully Cedric can confirm this as I don’t know the spec. > > > > >> Right now we have a second one because the first is not > consistently > > > > >> returning pointers that either do or do not need to be unrefd. > > > > >> > > > > >> Andy > > > > >> On Tue, 26 Dec 2017 at 04:25, Carsten Haitzler < > ras...@rasterman.com> > > > > >> wrote: > > > > >> > > > > >>> On Sun, 24 Dec 2017 09:16:08 +0000 Andrew Williams < > > > a...@andywilliams.me> > > > > >>> said: > > > > >>> > > > > >>> > Are you trolling me now? > > > > >>> > > > > >>> no. you said its inconsistent. it's consistent. it has a simple > rule. > > > > >>> > > > > >>> http://www.dictionary.com/browse/consistent > > > > >>> > > > > >>> it consistently adheres to the same principles. i described them. > > > > >>> > > > > >>> > A method that does two different things depending on some magic > > > value / > > > > >>> > > > > >>> it's not a MAGIC value. it's a parent object handle. it's far > from > > > magic. > > > > >>> it's > > > > >>> "put this object into THIS box here, or into NO box and give it > to > > > me" > > > > >>> based on > > > > >>> that option. > > > > >>> > > > > >>> > null flag is a code smell (see Clean Coders if this is not > > > familiar). > > > > >>> > Consider this method: > > > > >>> > > > > > >>> > ptr get_mem(string poolname, long bytes) { > > > > >>> > If (poolname == NULL) > > > > >>> > return malloc(bytes); // MUST be freed > > > > >>> > else > > > > >>> > return get_pool(poolname).borrow(bytes); // must NOT be freed > > > > >>> > } > > > > >>> > > > > > >>> > Do you think that is consistent? The user is not sure without > > > inspecting > > > > >>> > the parameter contents whether or not the should free(). This > is > > > > >>> > conceptually what we are setting up. > > > > >>> > > > > >>> #define efl_add_noparent(klass, ...) efl_add(klass, NULL, ## > > > __VA_ARGS__) > > > > >>> > > > > >>> happy? you can have a macro to hide the parent if NULL. but > it'll be > > > used > > > > >>> fairly rarely. > > > > >>> > > > > >>> > Back to our efl_add - what would be consistent is this: > > > > >>> > > > > > >>> > Eo* efl_add(klass, ... constructors ...); // must be unrefd (no > > > parent) > > > > >>> > > > > > >>> > Eo* efl_add_child(klass, parent, ... constructors ... ); // > parent > > > must > > > > >>> not > > > > >>> > be null, should not be unrefd > > > > >>> > > > > > >>> > That is consistent. It is also compliant with the V7 vote. It > > > still has > > > > >>> the > > > > >>> > race condition but is much easier to read. I know from the > method > > > names > > > > >>> > what is expected. > > > > >>> > > > > >>> your proposal was to have efl_add return void. the above is > better > > > for > > > > >>> sure. i > > > > >>> see we were walking down similar paths. > > > > >>> > > > > >>> i still dislike the above because it just makes the api more > verbose > > > for > > > > >>> the > > > > >>> sake of special-casing "parent == NULL". i dislike it. this > isn't a > > > magic > > > > >>> "bool" that turns on or off behaviour. that is actually not > great. > > > you > > > > >>> read code > > > > >>> like > > > > >>> > > > > >>> func_do_something(obj, EINA_TRUE, EINA_FALSE, EINA_TRUE); > > > > >>> > > > > >>> ... and what are the 3 bools? it's not clear or obvious. but > with a > > > > >>> constructor > > > > >>> like efl_add firstly it's incredibly common so it's something > that > > > will be > > > > >>> learned very quickly, and the typing already tells you it's an > object > > > > >>> handle. > > > > >>> and you should have learned already that it's the parent object > (or > > > no > > > > >>> parent > > > > >>> at all if NULL). > > > > >>> > > > > >>> why do i dislike it? we now go from 2 constructors (efl_add and > > > > >>> efl_add_ref) to > > > > >>> 4 (efl_add, efl_child_add, efl_add_ref, efl_child_add_ref). i > > > dislike this > > > > >>> "explosion" just to hide the parent arg being NULL. > > > > >>> > > > > >>> > Thoughts? > > > > >>> > On Sun, 24 Dec 2017 at 03:33, Carsten Haitzler < > > > ras...@rasterman.com> > > > > >>> wrote: > > > > >>> > > > > > >>> > > On Sat, 23 Dec 2017 11:30:58 +0000 Andrew Williams < > > > > >>> a...@andywilliams.me> > > > > >>> > > said: > > > > >>> > > > > > > >>> > > > Hi, > > > > >>> > > > > > > > >>> > > > As this thread seems to be descending into word games and > > > (insert > > > > >>> > > > appropriate word) contests I will reiterate my concern: > > > > >>> > > > > > > > >>> > > > efl_add is inconsistent and that should be addressed. > > > > >>> > > > > > > >>> > > do it's not. i explained already that it is not. i'll repeat > > > again. > > > > >>> it's > > > > >>> > > consistent: > > > > >>> > > > > > > >>> > > if parent == valid object, then ref is owned by parent > > > > >>> > > else ref is owned by caller/scope. > > > > >>> > > > > > > >>> > > that is consistent. > > > > >>> > > > > > > >>> > > > I hope that is clear enough > > > > >>> > > > Andy > > > > >>> > > > > > > > >>> > > > > > > > >>> > > > On Thu, 21 Dec 2017 at 13:15, Andrew Williams < > > > a...@andywilliams.me > > > > >>> > > > > > >>> > > wrote: > > > > >>> > > > > > > > >>> > > > > 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 > > > > >>> > > > > > > > > >>> > > > > 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. > > > > >>> > > > > > > > > >>> > > > > 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. > > > > >>> > > > > > > > > >>> > > > > 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 > > > > >>> > > > > > > > > >>> > > > -- > > > > >>> > > > 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 > > > > >> > > > > > -- > > > > > 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 > > > > > > > > > > > > > > > > -- > > > > Felipe Magno de Almeida > > > > > > > > > > > > > -- > > > ------------- Codito, ergo sum - "I code, therefore I am" > -------------- > > > Carsten Haitzler - ras...@rasterman.com > > > > > > > > > > > > > ------------------------------------------------------------------------------ > > > 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 > > > > > -- > > 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 ------------------------------------------------------------------------------ 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