ion_ | keybuk: Have you had a chance to waste cycles with my email yet? :-) | 15:47 |
---|---|---|
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 | 15:50 |
ion_ | Alright. | 16:01 |
ion_ | No hurry. | 16:01 |
Keybuk | I originally wrote nih_alloc with ref-counting | 16:02 |
Keybuk | I forget why I removed it | 16:02 |
ion_ | keybuk: Do you think you’ll still be able to take a look at my commit today? :-) | 21:46 |
Keybuk | ion_: why is it a uint32_t ? | 23:30 |
Keybuk | unless you have specific need for a 32-bit type, shouldn't that just be "unsigned int" ? | 23:31 |
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:33 |
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:34 |
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:38 |
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:39 |
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:40 |
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:41 |
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:42 |
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:43 |
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:44 |
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:45 |
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:46 |
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:47 |
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:48 |
ion_ | It would resemble libnih *a lot* since i quite like libnih, though, so i’d rather avoid duplication of effort. | 23:49 |
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:50 |
ion_ | Ok, i’ll take a look. :-) | 23:51 |
Keybuk | I think other objects can hold secondary references on an object | 23:51 |
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:52 |
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:53 |
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:54 |
Keybuk | I don't know what you want the ref counting for? | 23:55 |
Amaranth | this reminds me of GInitiallyUnowned | 23:56 |
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:57 |
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. | 23:59 |
Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!