X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftal%2Ftal.c;h=1eaa5749476aa3abd23992c16167b031c47175f6;hp=ce1220701e6640fd43357af0d427c4aa6a380883;hb=8d14165ac039a97617f2b63ee70754b855776013;hpb=4814c4c79cc00ba61f865075af9ca8f919f6f370 diff --git a/ccan/tal/tal.c b/ccan/tal/tal.c index ce122070..1eaa5749 100644 --- a/ccan/tal/tal.c +++ b/ccan/tal/tal.c @@ -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; @@ -680,13 +670,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 +688,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 +701,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 +760,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 +796,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);