]> git.ozlabs.org Git - ccan/blobdiff - ccan/tal/tal.c
tal: make tal_next() only return immediate children.
[ccan] / ccan / tal / tal.c
index ce1220701e6640fd43357af0d427c4aa6a380883..8360b2520690c31a594da58a4cef8cb57889d87e 100644 (file)
@@ -76,7 +76,6 @@ static void *(*allocfn)(size_t size) = malloc;
 static void *(*resizefn)(void *, size_t size) = realloc;
 static void (*freefn)(void *) = free;
 static void (*errorfn)(const char *msg) = (void *)abort;
-static bool initialized = false;
 /* Count on non-destrutor notifiers; often stays zero. */
 static size_t notifiers = 0;
 
@@ -101,23 +100,19 @@ static struct children *ignore_destroying_bit(struct children *parent_child)
 }
 
 /* This means valgrind can see leaks. */
-static void tal_cleanup(void)
+void tal_cleanup(void)
 {
        struct tal_hdr *i;
 
-       while ((i = list_top(&null_parent.c.children, struct tal_hdr, list)))
+       while ((i = list_top(&null_parent.c.children, struct tal_hdr, list))) {
                list_del(&i->list);
+               memset(i, 0, sizeof(*i));
+       }
 
        /* Cleanup any taken pointers. */
        take_cleanup();
 }
 
-/* For allocation failures inside ccan/take */
-static void take_alloc_failed(const void *p)
-{
-       tal_free(p);
-}
-
 /* We carefully start all real properties with a zero byte. */
 static bool is_literal(const struct prop_hdr *prop)
 {
@@ -344,11 +339,6 @@ static bool add_child(struct tal_hdr *parent, struct tal_hdr *child)
        struct children *children = find_property(parent, CHILDREN);
 
         if (!children) {
-               if (unlikely(!initialized)) {
-                       atexit(tal_cleanup);
-                       take_allocfail(take_alloc_failed);
-                       initialized = true;
-               }
                children = add_child_property(parent, child);
                if (!children)
                        return false;
@@ -640,31 +630,16 @@ tal_t *tal_first(const tal_t *root)
        return from_tal_hdr(c);
 }
 
-tal_t *tal_next(const tal_t *root, const tal_t *prev)
+tal_t *tal_next(const tal_t *prev)
 {
-        struct tal_hdr *c, *t = debug_tal(to_tal_hdr(prev)), *top;
-
-        /* Children? */
-       c = first_child(t);
-       if (c)
-               return from_tal_hdr(c);
-
-        top = to_tal_hdr_or_null(root);
-        do {
-               struct tal_hdr *next;
-               struct list_node *end;
+        struct tal_hdr *next, *prevhdr = debug_tal(to_tal_hdr(prev));
+       struct list_head *head;
 
-               end = &ignore_destroying_bit(t->parent_child)->children.n;
-
-               next = list_entry(t->list.next, struct tal_hdr, list);
-               if (&next->list != end)
-                       return from_tal_hdr(next);
-
-                /* OK, go back to parent. */
-                t = ignore_destroying_bit(t->parent_child)->parent;
-        } while (t != top);
-
-        return NULL;
+       head = &ignore_destroying_bit(prevhdr->parent_child)->children;
+       next = list_next(head, prevhdr, list);
+       if (!next)
+               return NULL;
+       return from_tal_hdr(next);
 }
 
 tal_t *tal_parent(const tal_t *ctx)
@@ -680,13 +655,13 @@ tal_t *tal_parent(const tal_t *ctx)
         return from_tal_hdr(ignore_destroying_bit(t->parent_child)->parent);
 }
 
-bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
+bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear)
 {
         struct tal_hdr *old_t, *t;
         struct children *child;
        struct prop_hdr **lenp;
        struct length len;
-       size_t extra = 0;
+       size_t extra = 0, elemsize = size;
 
         old_t = debug_tal(to_tal_hdr(*ctxp));
 
@@ -698,7 +673,8 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
                /* Copy here, in case we're shrinking! */
                len = *(struct length *)*lenp;
                extra = extra_for_length(size);
-       }
+       } else /* If we don't have an old length, we can't clear! */
+               assert(!clear);
 
         t = resizefn(old_t, sizeof(struct tal_hdr) + size + extra);
        if (!t) {
@@ -710,6 +686,12 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
        if (lenp) {
                struct length *new_len;
 
+               /* Clear between old end and new end. */
+               if (clear && count > len.count) {
+                       char *old_end = (char *)(t + 1) + len.count * elemsize;
+                       memset(old_end, 0, elemsize * (count - len.count));
+               }
+
                new_len = (struct length *)((char *)(t + 1) + size);
                len.count = count;
                *new_len = len;
@@ -763,7 +745,7 @@ bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count)
        assert(src < *ctxp
               || (char *)src >= (char *)(*ctxp) + (size * old_count));
 
-       if (!tal_resize_(ctxp, size, old_count + count))
+       if (!tal_resize_(ctxp, size, old_count + count, false))
                goto out;
 
        memcpy((char *)*ctxp + size * old_count, src, count * size);
@@ -799,7 +781,7 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
        if (taken(p)) {
                if (unlikely(!p))
                        return NULL;
-               if (unlikely(!tal_resize_((void **)&p, size, n + extra)))
+               if (unlikely(!tal_resize_((void **)&p, size, n + extra, false)))
                        return tal_free(p);
                if (unlikely(!tal_steal(ctx, p)))
                        return tal_free(p);