2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 inspired by http://swapped.cc/halloc/
41 /* use this to force every realloc to change the pointer, to stress test
42 code that might not cope */
43 #define ALWAYS_REALLOC 0
46 #define MAX_TALLOC_SIZE 0x10000000
47 #define TALLOC_MAGIC 0xe814ec4f
48 #define TALLOC_MAGIC_FREE 0x7faebef3
49 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
51 /* by default we abort when given a bad pointer (such as when talloc_free() is called
52 on a pointer that came from malloc() */
54 #define TALLOC_ABORT(reason) abort()
57 #ifndef discard_const_p
58 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
59 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
61 # define discard_const_p(type, ptr) ((type *)(ptr))
65 /* this null_context is only used if talloc_enable_leak_report() or
66 talloc_enable_leak_report_full() is called, otherwise it remains
69 static const void *null_context;
70 static void *cleanup_context;
73 struct talloc_reference_handle {
74 struct talloc_reference_handle *next, *prev;
78 typedef int (*talloc_destructor_t)(void *);
81 struct talloc_chunk *next, *prev;
82 struct talloc_chunk *parent, *child;
83 struct talloc_reference_handle *refs;
86 talloc_destructor_t destructor;
90 /* panic if we get a bad magic value */
91 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
93 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
94 if (tc->magic != TALLOC_MAGIC) {
95 if (tc->magic == TALLOC_MAGIC_FREE) {
96 TALLOC_ABORT("Bad talloc magic value - double free");
98 TALLOC_ABORT("Bad talloc magic value - unknown value");
105 /* hook into the front of the list */
106 #define _TLIST_ADD(list, p) \
110 (p)->next = (p)->prev = NULL; \
112 (list)->prev = (p); \
113 (p)->next = (list); \
119 /* remove an element from a list - element doesn't have to be in list. */
120 #define _TLIST_REMOVE(list, p) \
122 if ((p) == (list)) { \
123 (list) = (p)->next; \
124 if (list) (list)->prev = NULL; \
126 if ((p)->prev) (p)->prev->next = (p)->next; \
127 if ((p)->next) (p)->next->prev = (p)->prev; \
129 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
134 return the parent chunk of a pointer
136 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
138 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
139 while (tc->prev) tc=tc->prev;
144 Allocate a bit of memory as a child of an existing pointer
146 void *_talloc(const void *context, size_t size)
148 struct talloc_chunk *tc;
150 if (context == NULL) {
151 context = null_context;
154 if (size >= MAX_TALLOC_SIZE) {
158 tc = malloc(sizeof(*tc)+size);
159 if (tc == NULL) return NULL;
162 tc->magic = TALLOC_MAGIC;
163 tc->destructor = NULL;
169 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
174 parent->child->parent = NULL;
177 _TLIST_ADD(parent->child, tc);
179 tc->next = tc->prev = tc->parent = NULL;
182 return (void *)(tc+1);
187 setup a destructor to be called on free of a pointer
188 the destructor should return 0 on success, or -1 on failure.
189 if the destructor fails then the free is failed, and the memory can
190 be continued to be used
192 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
194 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
195 tc->destructor = destructor;
199 increase the reference count on a piece of memory.
201 void talloc_increase_ref_count(const void *ptr)
203 talloc_reference(null_context, ptr);
207 helper for talloc_reference()
209 static int talloc_reference_destructor(void *ptr)
211 struct talloc_reference_handle *handle = ptr;
212 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
213 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
214 if (tc1->destructor != (talloc_destructor_t)-1) {
215 tc1->destructor = NULL;
217 _TLIST_REMOVE(tc2->refs, handle);
223 make a secondary reference to a pointer, hanging off the given context.
224 the pointer remains valid until both the original caller and this given
227 the major use for this is when two different structures need to reference the
228 same underlying data, and you want to be able to free the two instances separately,
231 void *talloc_reference(const void *context, const void *ptr)
233 struct talloc_chunk *tc;
234 struct talloc_reference_handle *handle;
235 if (ptr == NULL) return NULL;
237 tc = talloc_chunk_from_ptr(ptr);
238 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
240 if (handle == NULL) return NULL;
242 /* note that we hang the destructor off the handle, not the
243 main context as that allows the caller to still setup their
244 own destructor on the context if they want to */
245 talloc_set_destructor(handle, talloc_reference_destructor);
246 handle->ptr = discard_const_p(void, ptr);
247 _TLIST_ADD(tc->refs, handle);
252 remove a secondary reference to a pointer. This undo's what
253 talloc_reference() has done. The context and pointer arguments
254 must match those given to a talloc_reference()
256 static int talloc_unreference(const void *context, const void *ptr)
258 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
259 struct talloc_reference_handle *h;
261 if (context == NULL) {
262 context = null_context;
265 for (h=tc->refs;h;h=h->next) {
266 struct talloc_chunk *p = talloc_parent_chunk(h);
267 if ((p==NULL && context==NULL) || p+1 == context) break;
273 talloc_set_destructor(h, NULL);
274 _TLIST_REMOVE(tc->refs, h);
280 remove a specific parent context from a pointer. This is a more
281 controlled varient of talloc_free()
283 int talloc_unlink(const void *context, void *ptr)
285 struct talloc_chunk *tc_p, *new_p;
292 if (context == NULL) {
293 context = null_context;
296 if (talloc_unreference(context, ptr) == 0) {
300 if (context == NULL) {
301 if (talloc_parent_chunk(ptr) != NULL) {
305 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
310 tc_p = talloc_chunk_from_ptr(ptr);
312 if (tc_p->refs == NULL) {
313 return talloc_free(ptr);
316 new_p = talloc_parent_chunk(tc_p->refs);
318 new_parent = new_p+1;
323 if (talloc_unreference(new_parent, ptr) != 0) {
327 talloc_steal(new_parent, ptr);
333 add a name to an existing pointer - va_list version
335 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
337 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
339 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
340 tc->name = talloc_vasprintf(ptr, fmt, ap);
342 talloc_set_name_const(tc->name, ".name");
347 add a name to an existing pointer
349 void talloc_set_name(const void *ptr, const char *fmt, ...)
353 talloc_set_name_v(ptr, fmt, ap);
358 more efficient way to add a name to a pointer - the name must point to a
361 void talloc_set_name_const(const void *ptr, const char *name)
363 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
368 create a named talloc pointer. Any talloc pointer can be named, and
369 talloc_named() operates just like talloc() except that it allows you
372 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
377 ptr = _talloc(context, size);
378 if (ptr == NULL) return NULL;
381 talloc_set_name_v(ptr, fmt, ap);
388 create a named talloc pointer. Any talloc pointer can be named, and
389 talloc_named() operates just like talloc() except that it allows you
392 void *talloc_named_const(const void *context, size_t size, const char *name)
396 ptr = _talloc(context, size);
401 talloc_set_name_const(ptr, name);
407 return the name of a talloc ptr, or "UNNAMED"
409 const char *talloc_get_name(const void *ptr)
411 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
412 if (tc->name == TALLOC_MAGIC_REFERENCE) {
422 this is for compatibility with older versions of talloc
424 void *talloc_init(const char *fmt, ...)
429 ptr = _talloc(NULL, 0);
430 if (ptr == NULL) return NULL;
433 talloc_set_name_v(ptr, fmt, ap);
441 free a talloc pointer. This also frees all child pointers of this
444 return 0 if the memory is actually freed, otherwise -1. The memory
445 will not be freed if the ref_count is > 1 or the destructor (if
446 any) returns non-zero
448 int talloc_free(void *ptr)
450 struct talloc_chunk *tc;
456 tc = talloc_chunk_from_ptr(ptr);
459 talloc_reference_destructor(tc->refs);
463 if (tc->destructor) {
464 talloc_destructor_t d = tc->destructor;
465 if (d == (talloc_destructor_t)-1) {
468 tc->destructor = (talloc_destructor_t)-1;
473 tc->destructor = NULL;
477 /* we need to work out who will own an abandoned child
478 if it cannot be freed. In priority order, the first
479 choice is owner of any remaining reference to this
480 pointer, the second choice is our parent, and the
481 final choice is the null context. */
482 void *child = tc->child+1;
483 const void *new_parent = null_context;
484 if (tc->child->refs) {
485 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
486 if (p) new_parent = p+1;
488 if (talloc_free(child) == -1) {
489 if (new_parent == null_context) {
490 struct talloc_chunk *p = talloc_parent_chunk(ptr);
491 if (p) new_parent = p+1;
493 talloc_steal(new_parent, child);
498 _TLIST_REMOVE(tc->parent->child, tc);
499 if (tc->parent->child) {
500 tc->parent->child->parent = tc->parent;
503 if (tc->prev) tc->prev->next = tc->next;
504 if (tc->next) tc->next->prev = tc->prev;
507 tc->magic = TALLOC_MAGIC_FREE;
516 A talloc version of realloc. The context argument is only used if
519 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
521 struct talloc_chunk *tc;
524 /* size zero is equivalent to free() */
530 if (size >= MAX_TALLOC_SIZE) {
534 /* realloc(NULL) is equavalent to malloc() */
536 return talloc_named_const(context, size, name);
539 tc = talloc_chunk_from_ptr(ptr);
541 /* don't allow realloc on referenced pointers */
546 /* by resetting magic we catch users of the old memory */
547 tc->magic = TALLOC_MAGIC_FREE;
550 new_ptr = malloc(size + sizeof(*tc));
552 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
556 new_ptr = realloc(tc, size + sizeof(*tc));
559 tc->magic = TALLOC_MAGIC;
564 tc->magic = TALLOC_MAGIC;
566 tc->parent->child = new_ptr;
569 tc->child->parent = new_ptr;
580 talloc_set_name_const(tc+1, name);
582 return (void *)(tc+1);
586 move a lump of memory from one talloc context to another return the
587 ptr on success, or NULL if it could not be transferred
589 void *talloc_steal(const void *new_ctx, const void *ptr)
591 struct talloc_chunk *tc, *new_tc;
597 if (new_ctx == NULL) {
598 new_ctx = null_context;
601 tc = talloc_chunk_from_ptr(ptr);
603 if (new_ctx == NULL) {
605 _TLIST_REMOVE(tc->parent->child, tc);
606 if (tc->parent->child) {
607 tc->parent->child->parent = tc->parent;
610 if (tc->prev) tc->prev->next = tc->next;
611 if (tc->next) tc->next->prev = tc->prev;
614 tc->parent = tc->next = tc->prev = NULL;
615 return discard_const_p(void, ptr);
618 new_tc = talloc_chunk_from_ptr(new_ctx);
621 return discard_const_p(void, ptr);
625 _TLIST_REMOVE(tc->parent->child, tc);
626 if (tc->parent->child) {
627 tc->parent->child->parent = tc->parent;
630 if (tc->prev) tc->prev->next = tc->next;
631 if (tc->next) tc->next->prev = tc->prev;
635 if (new_tc->child) new_tc->child->parent = NULL;
636 _TLIST_ADD(new_tc->child, tc);
638 return discard_const_p(void, ptr);
642 return the total size of a talloc pool (subtree)
644 off_t talloc_total_size(const void *ptr)
647 struct talloc_chunk *c, *tc;
656 tc = talloc_chunk_from_ptr(ptr);
659 for (c=tc->child;c;c=c->next) {
660 total += talloc_total_size(c+1);
666 return the total number of blocks in a talloc pool (subtree)
668 off_t talloc_total_blocks(const void *ptr)
671 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
674 for (c=tc->child;c;c=c->next) {
675 total += talloc_total_blocks(c+1);
681 return the number of external references to a pointer
683 static int talloc_reference_count(const void *ptr)
685 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
686 struct talloc_reference_handle *h;
689 for (h=tc->refs;h;h=h->next) {
696 report on memory usage by all children of a pointer, giving a full tree view
698 static void talloc_report_depth(const void *ptr, FILE *f, int depth)
700 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
702 for (c=tc->child;c;c=c->next) {
703 if (c->name == TALLOC_MAGIC_REFERENCE) {
704 struct talloc_reference_handle *handle = (void *)(c+1);
705 const char *name2 = talloc_get_name(handle->ptr);
706 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
708 const char *name = talloc_get_name(c+1);
709 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
712 (unsigned long)talloc_total_size(c+1),
713 (unsigned long)talloc_total_blocks(c+1),
714 talloc_reference_count(c+1));
715 talloc_report_depth(c+1, f, depth+1);
722 report on memory usage by all children of a pointer, giving a full tree view
724 void talloc_report_full(const void *ptr, FILE *f)
729 if (ptr == NULL) return;
731 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
732 talloc_get_name(ptr),
733 (unsigned long)talloc_total_size(ptr),
734 (unsigned long)talloc_total_blocks(ptr));
736 talloc_report_depth(ptr, f, 1);
740 report on memory usage by all children of a pointer
742 void talloc_report(const void *ptr, FILE *f)
744 struct talloc_chunk *c, *tc;
749 if (ptr == NULL) return;
751 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
752 talloc_get_name(ptr),
753 (unsigned long)talloc_total_size(ptr),
754 (unsigned long)talloc_total_blocks(ptr));
756 tc = talloc_chunk_from_ptr(ptr);
758 for (c=tc->child;c;c=c->next) {
759 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
760 talloc_get_name(c+1),
761 (unsigned long)talloc_total_size(c+1),
762 (unsigned long)talloc_total_blocks(c+1));
768 report on any memory hanging off the null context
770 static void talloc_report_null(void)
772 if (talloc_total_size(null_context) != 0) {
773 talloc_report(null_context, stderr);
778 report on any memory hanging off the null context
780 static void talloc_report_null_full(void)
782 if (talloc_total_size(null_context) != 0) {
783 talloc_report_full(null_context, stderr);
788 enable leak reporting on exit
790 void talloc_enable_leak_report(void)
792 null_context = talloc_named_const(NULL, 0, "null_context");
793 atexit(talloc_report_null);
797 enable full leak reporting on exit
799 void talloc_enable_leak_report_full(void)
801 null_context = talloc_named_const(NULL, 0, "null_context");
802 atexit(talloc_report_null_full);
806 talloc and zero memory.
808 void *_talloc_zero(const void *ctx, size_t size, const char *name)
810 void *p = talloc_named_const(ctx, size, name);
813 memset(p, '\0', size);
821 memdup with a talloc.
823 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
825 void *newp = talloc_named_const(t, size, name);
828 memcpy(newp, p, size);
837 char *talloc_strdup(const void *t, const char *p)
843 ret = talloc_memdup(t, p, strlen(p) + 1);
845 talloc_set_name_const(ret, ret);
851 strndup with a talloc
853 char *talloc_strndup(const void *t, const char *p, size_t n)
858 for (len=0; p[len] && len<n; len++) ;
860 ret = _talloc(t, len + 1);
861 if (!ret) { return NULL; }
864 talloc_set_name_const(ret, ret);
870 #define VA_COPY(dest, src) __va_copy(dest, src)
872 #define VA_COPY(dest, src) (dest) = (src)
876 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
884 len = vsnprintf(NULL, 0, fmt, ap2);
886 ret = _talloc(t, len+1);
889 vsnprintf(ret, len+1, fmt, ap2);
890 talloc_set_name_const(ret, ret);
898 Perform string formatting, and return a pointer to newly allocated
899 memory holding the result, inside a memory pool.
901 char *talloc_asprintf(const void *t, const char *fmt, ...)
907 ret = talloc_vasprintf(t, fmt, ap);
914 * Realloc @p s to append the formatted result of @p fmt and @p ap,
915 * and return @p s, which may have moved. Good for gradually
916 * accumulating output into a string buffer.
919 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
921 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
933 len = vsnprintf(NULL, 0, fmt, ap2);
935 s = talloc_realloc(NULL, s, s_len + len+1);
940 vsnprintf(s+s_len, len+1, fmt, ap2);
941 talloc_set_name_const(s, s);
947 Realloc @p s to append the formatted result of @p fmt and return @p
948 s, which may have moved. Good for gradually accumulating output
949 into a string buffer.
951 char *talloc_asprintf_append(char *s, const char *fmt, ...)
956 s = talloc_vasprintf_append(s, fmt, ap);
962 alloc an array, checking for integer overflow in the array size
964 void *talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
966 if (count >= MAX_TALLOC_SIZE/el_size) {
969 return talloc_named_const(ctx, el_size * count, name);
973 alloc an zero array, checking for integer overflow in the array size
975 void *talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
977 if (count >= MAX_TALLOC_SIZE/el_size) {
980 return _talloc_zero(ctx, el_size * count, name);
985 realloc an array, checking for integer overflow in the array size
987 void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
989 if (count >= MAX_TALLOC_SIZE/el_size) {
992 ptr = talloc_realloc(ctx, ptr, el_size * count);
994 talloc_set_name_const(ptr, name);
1000 a function version of talloc_realloc(), so it can be passed as a function pointer
1001 to libraries that want a realloc function (a realloc function encapsulates
1002 all the basic capabilities of an allocation library, which is why this is useful)
1004 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1006 return _talloc_realloc(context, ptr, size, NULL);
1010 static void talloc_autofree(void)
1012 talloc_free(cleanup_context);
1013 cleanup_context = NULL;
1017 return a context which will be auto-freed on exit
1018 this is useful for reducing the noise in leak reports
1020 void *talloc_autofree_context(void)
1022 if (cleanup_context == NULL) {
1023 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1024 atexit(talloc_autofree);
1026 return cleanup_context;