[15:47] <ion_> keybuk: Have you had a chance to waste cycles with my email yet? :-)
[15:50] <Keybuk> not even read it yet
[15:50] <Keybuk> only returned from holiday this morning
[15:50] <Keybuk> and haven't done e-mail catch-up
[16:01] <ion_> Alright.
[16:01] <ion_> No hurry.
[16:02] <Keybuk> I originally wrote nih_alloc with ref-counting
[16:02] <Keybuk> I forget why I removed it
[21:46] <ion_> keybuk: Do you think you’ll still be able to take a look at my commit today? :-)
[23:30] <Keybuk> ion_: why is it a uint32_t ?
[23:31] <Keybuk> unless you have specific need for a 32-bit type, shouldn't that just be "unsigned int" ?
[23:33] <ion_> Heh, i just thought “whatever, uint32_t is shorter to type and it’s not as if it’s too small for a refcount”. :-P
[23:34] <Keybuk> it's reasonably good practice to avoid the "fixed length" types unless you really want a fixed length
[23:34] <ion_> Ok, i’ll keep that in mind from now on.
[23:38] <Keybuk> ah, now I remember why I didn't go with reference counting
[23:38] <Keybuk> it made the world tricky when dealing with parents
[23:38] <Keybuk> if you return objects with a ref count as 1 when parent = NULL
[23:39] <Keybuk> and the parent holds a ref on the object
[23:39] <Keybuk> then surely the returned object has to have a ref count of 1 when parent != NULL (ie. the parent)
[23:39] <Keybuk> which didn't actually do what you want
[23:39] <Keybuk> so you had to have the parents *not* reference the object
[23:39] <ion_> Oh, perhaps i forgot to document it, but the refcount is increased when it’s added to a parent.
[23:39] <Keybuk> since that's actually what you are after
[23:40] <Keybuk> but then how do you deal with a child object being referenced when its parent is freed?
[23:40] <Keybuk> sorry, not explaining well
[23:40] <Amaranth> how can a child not have a parent? :)
[23:41] <Amaranth> dunno what exactly you're talking about but i'm thinking the child would get a new parent?
[23:41] <Keybuk> a = nih_new (NULL, void *);
[23:41] <Keybuk> that has a refcount of 1
[23:41] <Keybuk> our reference
[23:41] <Amaranth> right
[23:41] <Keybuk> b = nih_new (a, void *);
[23:41] <Keybuk> that has a refcount of 2
[23:41] <Amaranth> ok
[23:41] <Keybuk> our reference
[23:42] <Keybuk> AND a reference by its parent
[23:42] <Keybuk> if I do nih_unref (a) now, what happens to b?
[23:42] <Amaranth> it has a refcount of 1?
[23:42] <ion_> Its refcount drops to 1
[23:42] <Amaranth> can you still use b?
[23:42] <Keybuk> so the object isn't freed when its parent is
[23:43] <Amaranth> not if someone else is holding on to it, why would it be?
[23:43] <Keybuk> the whole point of using the hierarchial allocator is to forget about objects if they have a parent
[23:43] <Keybuk> imagine
[23:43] <Keybuk>   a = nih_new (NULL, SomeStructure);
[23:43] <ion_> True...
[23:43] <Keybuk>  a->title = nih_strdup (a, "foo");
[23:43] <Keybuk>  a->description = nih_strdup (a, "some long description");
[23:44] <Keybuk> if a reference is left open for me, I now have to remember to nih_unref those as well
[23:44] <Keybuk> doubling the length of code
[23:44] <Amaranth> but wait, wouldn't a->title go away when a does?
[23:44] <Keybuk> no
[23:44] <Keybuk> because its refcount is 2
[23:44] <Keybuk> losing its parent would only decrease it to 1, so it would stay
[23:44] <Amaranth> but a is gone, how can a->title exist?
[23:45] <Keybuk> the alternative way would be the refcount of any returned object to always be 1
[23:45] <ion_> Actually, what i’d like to have would be the possibility of adding a child to multiple parents – or rather “containers” – so that each one references the child once. But granted, that’s something completely different than using the parent to automatically free the kids.
[23:45] <Keybuk> if its parent is NULL, then its 1 (yours)
[23:45] <Keybuk> if the parent is non-NULL, then its 1 (the parent)
[23:45] <Amaranth> but then you're not really doing refcounting
[23:45] <Keybuk> but then you can't unref the child yourself, since you don't have a reference :-)
[23:45] <Keybuk> ion_: sure
[23:45] <Keybuk> that's a refcounting allocator ;)
[23:46] <Keybuk> not a hierarchial one
[23:46] <Keybuk> it'd be a good different allocator, but I don't think you can bolt it onto an h one
[23:46] <ion_> tss, the author of liblib (the “standard library” dovecot and icecap use) uses memory pools to implement the following:
[23:46] <ion_> foo_push (pool);
[23:46] <ion_> Allocate stuff using pool
[23:47] <ion_> foo_pop (pool); // Everything you allocated above is freed
[23:47] <ion_> But that solves a different problem.
[23:47] <Keybuk> yeah, it's a bit like obstacks
[23:47] <Amaranth> that sounds like what nih has now
[23:47] <Keybuk> he wrote a great paper on why he did it that way, instead of just using alloca
[23:48] <ion_> I wonder whether i’ll end up NIHing my own “standard library” that is based on refcounting, since it would fit my application quite well... :-P
[23:48] <Keybuk> interestingly, talloc (a description of which is what nih_alloc is roughly based on) does have ref-counting
[23:49] <ion_> It would resemble libnih *a lot* since i quite like libnih, though, so i’d rather avoid duplication of effort.
[23:50] <ion_> Perhaps there’s a way to implement refcounting without breaking the hierarchical allocation. I’ll have to think about it when my brain is less exhausted.
[23:50] <Keybuk> grab the samba source and look though source/lib/talloc.c and work out how Tridge does it? :p
[23:51] <ion_> Ok, i’ll take a look. :-)
[23:51] <Keybuk> I think other objects can hold secondary references on an object
[23:52] <Keybuk> and if the parent is freed, the object is reparented to the first secondary reference
[23:52] <Keybuk> "god parents" if you like
[23:52] <Keybuk>  a = nih_new (NULL, void *);
[23:52] <ion_> A random thought: if nih_new is called with a parent, it’s still initialized with a refcount of one and you’re forbidden from calling nih_unref on the resulting object. Would that work?
[23:52] <Keybuk>  b = nih_new (a, void *);
[23:52] <Keybuk>  c = nih_new (NULL, void *);
[23:52] <Keybuk>  nih_alloc_reference (c, b);
[23:52] <Keybuk>  nih_free (a);
[23:52] <Keybuk>  /* parent of b is now c */
[23:53] <Keybuk> ion_: then you can't free the object independently later since you don't hold a ref on it
[23:53] <Keybuk> (not without breaking ref counting semantics anyway)
[23:54] <ion_> For own storage, you could then nih_ref it. :-P But yeah, that would be cumbersome.
[23:54] <Keybuk> the god parent thing might work quite nicely though
[23:55] <Keybuk> I don't know what you want the ref counting for?
[23:56] <Amaranth> this reminds me of GInitiallyUnowned
[23:57] <Amaranth> i mean, in this case it's initially owned by the parent but it's the same concept
[23:57] <Amaranth> you don't want the creator to have a reference
[23:59] <ion_> For instance, in an OpenGL engine i’m working on, a texture object can be attached to a number of mesh objects. I want the meshes to reference the texture, and unref it when they’re being freed.