1 /* Licensed under LGPL - see LICENSE file for details */
2 #include <ccan/tal/talloc/talloc.h>
6 static void (*errorfn)(const char *msg) = (void *)abort;
8 static void COLD call_error(const char *msg)
13 static void *error_on_null(void *p, const char *msg)
20 void *tal_talloc_(const tal_t *ctx, size_t bytes, bool clear,
26 ret = _talloc_zero(ctx, bytes, label);
28 ret = talloc_named_const(ctx, bytes, label);
30 return error_on_null(ret, "allocation failure");
33 void *tal_talloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear,
39 ret = _talloc_zero_array(ctx, bytes, count, label);
41 ret = _talloc_array(ctx, bytes, count, label);
43 return error_on_null(ret, "array allocation failure");
46 void *tal_talloc_free_(const tal_t *ctx)
48 int saved_errno = errno;
49 talloc_free((void *)ctx);
54 bool tal_talloc_set_name_(tal_t *ctx, const char *name, bool literal)
57 name = talloc_strdup(ctx, name);
59 call_error("set_name allocation failure");
63 talloc_set_name_const(ctx, name);
67 const char *tal_talloc_name_(const tal_t *ctx)
69 const char *p = talloc_get_name(ctx);
70 if (p && unlikely(strcmp(p, "UNNAMED") == 0))
75 static bool adjust_size(size_t *size, size_t count)
77 /* Multiplication wrap */
78 if (count && unlikely(*size * count / *size != count))
83 /* Make sure we don't wrap adding header. */
84 if (*size + 1024 < 1024)
88 call_error("allocation size overflow");
92 void *tal_talloc_dup_(const tal_t *ctx, const void *p, size_t size,
93 size_t n, size_t extra, const char *label)
98 if (!adjust_size(&nbytes, n)) {
104 /* Beware addition overflow! */
106 call_error("dup size overflow");
115 if (unlikely(!tal_talloc_resize_((void **)&p, size, n + extra)))
117 if (unlikely(!tal_steal(ctx, p)))
122 ret = tal_talloc_arr_(ctx, size, n + extra, false, label);
124 memcpy(ret, p, nbytes);
128 bool tal_talloc_resize_(tal_t **ctxp, size_t size, size_t count)
132 if (unlikely(count == 0)) {
134 newp = talloc_size(talloc_parent(*ctxp), 0);
136 call_error("Resize failure");
144 /* count is unsigned, not size_t, so check for overflow here! */
145 if ((unsigned)count != count) {
146 call_error("Resize overflos");
150 newp = _talloc_realloc_array(NULL, *ctxp, size, count, NULL);
152 call_error("Resize failure");
159 bool tal_talloc_expand_(tal_t **ctxp, const void *src, size_t size, size_t count)
162 size_t old_count = talloc_get_size(*ctxp) / size;
164 /* Check for additive overflow */
165 if (old_count + count < count) {
166 call_error("dup size overflow");
170 /* Don't point src inside thing we're expanding! */
172 || (char *)src >= (char *)(*ctxp) + (size * old_count));
174 if (!tal_talloc_resize_(ctxp, size, old_count + count))
177 memcpy((char *)*ctxp + size * old_count, src, count * size);
186 /* Sucky inline hash table implementation, to avoid deps. */
187 #define HTABLE_BITS 10
189 struct destructor *next;
191 void (*destroy)(void *me);
193 static struct destructor *destr_hash[1 << HTABLE_BITS];
195 static unsigned int hash_ptr(const void *p)
197 unsigned long h = (unsigned long)p / sizeof(void *);
199 return (h ^ (h >> HTABLE_BITS)) & ((1 << HTABLE_BITS) - 1);
202 static int tal_talloc_destroy(const tal_t *ctx)
204 struct destructor **d = &destr_hash[hash_ptr(ctx)];
206 if ((*d)->ctx == ctx) {
207 struct destructor *this = *d;
208 this->destroy((void *)ctx);
216 bool tal_talloc_add_destructor_(const tal_t *ctx, void (*destroy)(void *me))
218 struct destructor *d = talloc(ctx, struct destructor);
222 d->next = destr_hash[hash_ptr(ctx)];
224 d->destroy = destroy;
225 destr_hash[hash_ptr(ctx)] = d;
226 talloc_set_destructor(ctx, tal_talloc_destroy);
230 bool tal_talloc_del_destructor_(const tal_t *ctx, void (*destroy)(void *me))
232 struct destructor **d = &destr_hash[hash_ptr(ctx)];
235 if ((*d)->ctx == ctx && (*d)->destroy == destroy) {
236 struct destructor *this = *d;
246 void tal_talloc_set_backend_(void *(*alloc_fn)(size_t size),
247 void *(*resize_fn)(void *, size_t size),
248 void (*free_fn)(void *),
249 void (*error_fn)(const char *msg))
255 talloc_set_abort_fn(error_fn);
258 bool tal_talloc_check_(const tal_t *ctx, const char *errorstr)
260 /* We can't really check, but this iterates (and may abort). */
261 return !ctx || talloc_total_blocks(ctx) >= 1;