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/
38 #ifdef HAVE_SYS_TYPES_H
39 #include <sys/types.h>
58 /* use this to force every realloc to change the pointer, to stress test
59 code that might not cope */
60 #define ALWAYS_REALLOC 0
63 #define MAX_TALLOC_SIZE 0x10000000
64 #define TALLOC_MAGIC 0xe814ec4f
65 #define TALLOC_MAGIC_FREE 0x7faebef3
66 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
68 /* by default we abort when given a bad pointer (such as when talloc_free() is called
69 on a pointer that came from malloc() */
71 #define TALLOC_ABORT(reason) abort()
74 #ifndef discard_const_p
75 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
76 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
78 # define discard_const_p(type, ptr) ((type *)(ptr))
82 /* this null_context is only used if talloc_enable_leak_report() or
83 talloc_enable_leak_report_full() is called, otherwise it remains
86 static const void *null_context;
87 static void *cleanup_context;
90 struct talloc_reference_handle {
91 struct talloc_reference_handle *next, *prev;
95 typedef int (*talloc_destructor_t)(void *);
98 struct talloc_chunk *next, *prev;
99 struct talloc_chunk *parent, *child;
100 struct talloc_reference_handle *refs;
103 talloc_destructor_t destructor;
107 /* panic if we get a bad magic value */
108 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
110 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
111 if (tc->magic != TALLOC_MAGIC) {
112 if (tc->magic == TALLOC_MAGIC_FREE) {
113 TALLOC_ABORT("Bad talloc magic value - double free");
115 TALLOC_ABORT("Bad talloc magic value - unknown value");
122 /* hook into the front of the list */
123 #define _TLIST_ADD(list, p) \
127 (p)->next = (p)->prev = NULL; \
129 (list)->prev = (p); \
130 (p)->next = (list); \
136 /* remove an element from a list - element doesn't have to be in list. */
137 #define _TLIST_REMOVE(list, p) \
139 if ((p) == (list)) { \
140 (list) = (p)->next; \
141 if (list) (list)->prev = NULL; \
143 if ((p)->prev) (p)->prev->next = (p)->next; \
144 if ((p)->next) (p)->next->prev = (p)->prev; \
146 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
151 return the parent chunk of a pointer
153 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
155 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
156 while (tc->prev) tc=tc->prev;
160 void *talloc_parent(const void *ptr)
162 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
163 return (void *)(tc+1);
167 Allocate a bit of memory as a child of an existing pointer
169 void *_talloc(const void *context, size_t size)
171 struct talloc_chunk *tc;
173 if (context == NULL) {
174 context = null_context;
177 if (size >= MAX_TALLOC_SIZE) {
181 tc = malloc(sizeof(*tc)+size);
182 if (tc == NULL) return NULL;
185 tc->magic = TALLOC_MAGIC;
186 tc->destructor = NULL;
192 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
197 parent->child->parent = NULL;
200 _TLIST_ADD(parent->child, tc);
202 tc->next = tc->prev = tc->parent = NULL;
205 return (void *)(tc+1);
210 setup a destructor to be called on free of a pointer
211 the destructor should return 0 on success, or -1 on failure.
212 if the destructor fails then the free is failed, and the memory can
213 be continued to be used
215 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
217 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
218 tc->destructor = destructor;
222 increase the reference count on a piece of memory.
224 void talloc_increase_ref_count(const void *ptr)
226 talloc_reference(null_context, ptr);
230 helper for talloc_reference()
232 static int talloc_reference_destructor(void *ptr)
234 struct talloc_reference_handle *handle = ptr;
235 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
236 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
237 if (tc1->destructor != (talloc_destructor_t)-1) {
238 tc1->destructor = NULL;
240 _TLIST_REMOVE(tc2->refs, handle);
246 make a secondary reference to a pointer, hanging off the given context.
247 the pointer remains valid until both the original caller and this given
250 the major use for this is when two different structures need to reference the
251 same underlying data, and you want to be able to free the two instances separately,
254 void *talloc_reference(const void *context, const void *ptr)
256 struct talloc_chunk *tc;
257 struct talloc_reference_handle *handle;
258 if (ptr == NULL) return NULL;
260 tc = talloc_chunk_from_ptr(ptr);
261 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
263 if (handle == NULL) return NULL;
265 /* note that we hang the destructor off the handle, not the
266 main context as that allows the caller to still setup their
267 own destructor on the context if they want to */
268 talloc_set_destructor(handle, talloc_reference_destructor);
269 handle->ptr = discard_const_p(void, ptr);
270 _TLIST_ADD(tc->refs, handle);
275 remove a secondary reference to a pointer. This undo's what
276 talloc_reference() has done. The context and pointer arguments
277 must match those given to a talloc_reference()
279 static int talloc_unreference(const void *context, const void *ptr)
281 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
282 struct talloc_reference_handle *h;
284 if (context == NULL) {
285 context = null_context;
288 for (h=tc->refs;h;h=h->next) {
289 struct talloc_chunk *p = talloc_parent_chunk(h);
290 if ((p==NULL && context==NULL) || p+1 == context) break;
296 talloc_set_destructor(h, NULL);
297 _TLIST_REMOVE(tc->refs, h);
303 remove a specific parent context from a pointer. This is a more
304 controlled varient of talloc_free()
306 int talloc_unlink(const void *context, void *ptr)
308 struct talloc_chunk *tc_p, *new_p;
315 if (context == NULL) {
316 context = null_context;
319 if (talloc_unreference(context, ptr) == 0) {
323 if (context == NULL) {
324 if (talloc_parent_chunk(ptr) != NULL) {
328 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
333 tc_p = talloc_chunk_from_ptr(ptr);
335 if (tc_p->refs == NULL) {
336 return talloc_free(ptr);
339 new_p = talloc_parent_chunk(tc_p->refs);
341 new_parent = new_p+1;
346 if (talloc_unreference(new_parent, ptr) != 0) {
350 talloc_steal(new_parent, ptr);
356 add a name to an existing pointer - va_list version
358 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
360 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
362 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
363 tc->name = talloc_vasprintf(ptr, fmt, ap);
365 talloc_set_name_const(tc->name, ".name");
370 add a name to an existing pointer
372 void talloc_set_name(const void *ptr, const char *fmt, ...)
376 talloc_set_name_v(ptr, fmt, ap);
381 more efficient way to add a name to a pointer - the name must point to a
384 void talloc_set_name_const(const void *ptr, const char *name)
386 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
391 create a named talloc pointer. Any talloc pointer can be named, and
392 talloc_named() operates just like talloc() except that it allows you
395 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
400 ptr = _talloc(context, size);
401 if (ptr == NULL) return NULL;
404 talloc_set_name_v(ptr, fmt, ap);
411 create a named talloc pointer. Any talloc pointer can be named, and
412 talloc_named() operates just like talloc() except that it allows you
415 void *talloc_named_const(const void *context, size_t size, const char *name)
419 ptr = _talloc(context, size);
424 talloc_set_name_const(ptr, name);
430 return the name of a talloc ptr, or "UNNAMED"
432 const char *talloc_get_name(const void *ptr)
434 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
435 if (tc->name == TALLOC_MAGIC_REFERENCE) {
446 check if a pointer has the given name. If it does, return the pointer,
447 otherwise return NULL
449 void *talloc_check_name(const void *ptr, const char *name)
452 if (ptr == NULL) return NULL;
453 pname = talloc_get_name(ptr);
454 if (pname == name || strcmp(pname, name) == 0) {
455 return discard_const_p(void, ptr);
462 this is for compatibility with older versions of talloc
464 void *talloc_init(const char *fmt, ...)
469 ptr = _talloc(NULL, 0);
470 if (ptr == NULL) return NULL;
473 talloc_set_name_v(ptr, fmt, ap);
480 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
481 should probably not be used in new code. It's in here to keep the talloc
482 code consistent across Samba 3 and 4.
484 void talloc_free_children(void *ptr)
486 struct talloc_chunk *tc;
492 tc = talloc_chunk_from_ptr(ptr);
495 /* we need to work out who will own an abandoned child
496 if it cannot be freed. In priority order, the first
497 choice is owner of any remaining reference to this
498 pointer, the second choice is our parent, and the
499 final choice is the null context. */
500 void *child = tc->child+1;
501 const void *new_parent = null_context;
502 if (tc->child->refs) {
503 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
504 if (p) new_parent = p+1;
506 if (talloc_free(child) == -1) {
507 if (new_parent == null_context) {
508 struct talloc_chunk *p = talloc_parent_chunk(ptr);
509 if (p) new_parent = p+1;
511 talloc_steal(new_parent, child);
517 free a talloc pointer. This also frees all child pointers of this
520 return 0 if the memory is actually freed, otherwise -1. The memory
521 will not be freed if the ref_count is > 1 or the destructor (if
522 any) returns non-zero
524 int talloc_free(void *ptr)
526 struct talloc_chunk *tc;
532 tc = talloc_chunk_from_ptr(ptr);
535 talloc_reference_destructor(tc->refs);
539 if (tc->destructor) {
540 talloc_destructor_t d = tc->destructor;
541 if (d == (talloc_destructor_t)-1) {
544 tc->destructor = (talloc_destructor_t)-1;
549 tc->destructor = NULL;
552 talloc_free_children(ptr);
555 _TLIST_REMOVE(tc->parent->child, tc);
556 if (tc->parent->child) {
557 tc->parent->child->parent = tc->parent;
560 if (tc->prev) tc->prev->next = tc->next;
561 if (tc->next) tc->next->prev = tc->prev;
564 tc->magic = TALLOC_MAGIC_FREE;
573 A talloc version of realloc. The context argument is only used if
576 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
578 struct talloc_chunk *tc;
581 /* size zero is equivalent to free() */
587 if (size >= MAX_TALLOC_SIZE) {
591 /* realloc(NULL) is equavalent to malloc() */
593 return talloc_named_const(context, size, name);
596 tc = talloc_chunk_from_ptr(ptr);
598 /* don't allow realloc on referenced pointers */
603 /* by resetting magic we catch users of the old memory */
604 tc->magic = TALLOC_MAGIC_FREE;
607 new_ptr = malloc(size + sizeof(*tc));
609 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
613 new_ptr = realloc(tc, size + sizeof(*tc));
616 tc->magic = TALLOC_MAGIC;
621 tc->magic = TALLOC_MAGIC;
623 tc->parent->child = new_ptr;
626 tc->child->parent = new_ptr;
637 talloc_set_name_const(tc+1, name);
639 return (void *)(tc+1);
643 move a lump of memory from one talloc context to another return the
644 ptr on success, or NULL if it could not be transferred.
645 passing NULL as ptr will always return NULL with no side effects.
647 void *talloc_steal(const void *new_ctx, const void *ptr)
649 struct talloc_chunk *tc, *new_tc;
655 if (new_ctx == NULL) {
656 new_ctx = null_context;
659 tc = talloc_chunk_from_ptr(ptr);
661 if (new_ctx == NULL) {
663 _TLIST_REMOVE(tc->parent->child, tc);
664 if (tc->parent->child) {
665 tc->parent->child->parent = tc->parent;
668 if (tc->prev) tc->prev->next = tc->next;
669 if (tc->next) tc->next->prev = tc->prev;
672 tc->parent = tc->next = tc->prev = NULL;
673 return discard_const_p(void, ptr);
676 new_tc = talloc_chunk_from_ptr(new_ctx);
679 return discard_const_p(void, ptr);
683 _TLIST_REMOVE(tc->parent->child, tc);
684 if (tc->parent->child) {
685 tc->parent->child->parent = tc->parent;
688 if (tc->prev) tc->prev->next = tc->next;
689 if (tc->next) tc->next->prev = tc->prev;
693 if (new_tc->child) new_tc->child->parent = NULL;
694 _TLIST_ADD(new_tc->child, tc);
696 return discard_const_p(void, ptr);
700 return the total size of a talloc pool (subtree)
702 off_t talloc_total_size(const void *ptr)
705 struct talloc_chunk *c, *tc;
714 tc = talloc_chunk_from_ptr(ptr);
717 for (c=tc->child;c;c=c->next) {
718 total += talloc_total_size(c+1);
724 return the total number of blocks in a talloc pool (subtree)
726 off_t talloc_total_blocks(const void *ptr)
729 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
732 for (c=tc->child;c;c=c->next) {
733 total += talloc_total_blocks(c+1);
739 return the number of external references to a pointer
741 static int talloc_reference_count(const void *ptr)
743 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
744 struct talloc_reference_handle *h;
747 for (h=tc->refs;h;h=h->next) {
754 report on memory usage by all children of a pointer, giving a full tree view
756 void talloc_report_depth(const void *ptr, FILE *f, int depth)
758 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
760 for (c=tc->child;c;c=c->next) {
761 if (c->name == TALLOC_MAGIC_REFERENCE) {
762 struct talloc_reference_handle *handle = (void *)(c+1);
763 const char *name2 = talloc_get_name(handle->ptr);
764 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
766 const char *name = talloc_get_name(c+1);
767 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
770 (unsigned long)talloc_total_size(c+1),
771 (unsigned long)talloc_total_blocks(c+1),
772 talloc_reference_count(c+1));
773 talloc_report_depth(c+1, f, depth+1);
780 report on memory usage by all children of a pointer, giving a full tree view
782 void talloc_report_full(const void *ptr, FILE *f)
787 if (ptr == NULL) return;
789 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
790 talloc_get_name(ptr),
791 (unsigned long)talloc_total_size(ptr),
792 (unsigned long)talloc_total_blocks(ptr));
794 talloc_report_depth(ptr, f, 1);
799 report on memory usage by all children of a pointer
801 void talloc_report(const void *ptr, FILE *f)
803 struct talloc_chunk *c, *tc;
808 if (ptr == NULL) return;
810 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
811 talloc_get_name(ptr),
812 (unsigned long)talloc_total_size(ptr),
813 (unsigned long)talloc_total_blocks(ptr));
815 tc = talloc_chunk_from_ptr(ptr);
817 for (c=tc->child;c;c=c->next) {
818 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
819 talloc_get_name(c+1),
820 (unsigned long)talloc_total_size(c+1),
821 (unsigned long)talloc_total_blocks(c+1));
827 report on any memory hanging off the null context
829 static void talloc_report_null(void)
831 if (talloc_total_size(null_context) != 0) {
832 talloc_report(null_context, stderr);
837 report on any memory hanging off the null context
839 static void talloc_report_null_full(void)
841 if (talloc_total_size(null_context) != 0) {
842 talloc_report_full(null_context, stderr);
847 enable tracking of the NULL context
849 void talloc_enable_null_tracking(void)
851 if (null_context == NULL) {
852 null_context = talloc_named_const(NULL, 0, "null_context");
857 enable leak reporting on exit
859 void talloc_enable_leak_report(void)
861 talloc_enable_null_tracking();
862 atexit(talloc_report_null);
866 enable full leak reporting on exit
868 void talloc_enable_leak_report_full(void)
870 talloc_enable_null_tracking();
871 atexit(talloc_report_null_full);
875 talloc and zero memory.
877 void *_talloc_zero(const void *ctx, size_t size, const char *name)
879 void *p = talloc_named_const(ctx, size, name);
882 memset(p, '\0', size);
890 memdup with a talloc.
892 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
894 void *newp = talloc_named_const(t, size, name);
897 memcpy(newp, p, size);
906 char *talloc_strdup(const void *t, const char *p)
912 ret = talloc_memdup(t, p, strlen(p) + 1);
914 talloc_set_name_const(ret, ret);
920 strndup with a talloc
922 char *talloc_strndup(const void *t, const char *p, size_t n)
927 for (len=0; len<n && p[len]; len++) ;
929 ret = _talloc(t, len + 1);
930 if (!ret) { return NULL; }
933 talloc_set_name_const(ret, ret);
939 #define VA_COPY(dest, src) va_copy(dest, src)
940 #elif defined(HAVE___VA_COPY)
941 #define VA_COPY(dest, src) __va_copy(dest, src)
943 #define VA_COPY(dest, src) (dest) = (src)
947 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
955 len = vsnprintf(NULL, 0, fmt, ap2);
957 ret = _talloc(t, len+1);
960 vsnprintf(ret, len+1, fmt, ap2);
961 talloc_set_name_const(ret, ret);
969 Perform string formatting, and return a pointer to newly allocated
970 memory holding the result, inside a memory pool.
972 char *talloc_asprintf(const void *t, const char *fmt, ...)
978 ret = talloc_vasprintf(t, fmt, ap);
985 * Realloc @p s to append the formatted result of @p fmt and @p ap,
986 * and return @p s, which may have moved. Good for gradually
987 * accumulating output into a string buffer.
990 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
992 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
994 struct talloc_chunk *tc;
999 return talloc_vasprintf(NULL, fmt, ap);
1002 tc = talloc_chunk_from_ptr(s);
1006 s_len = tc->size - 1;
1007 len = vsnprintf(NULL, 0, fmt, ap2);
1009 s = talloc_realloc(NULL, s, char, s_len + len+1);
1010 if (!s) return NULL;
1014 vsnprintf(s+s_len, len+1, fmt, ap2);
1015 talloc_set_name_const(s, s);
1021 Realloc @p s to append the formatted result of @p fmt and return @p
1022 s, which may have moved. Good for gradually accumulating output
1023 into a string buffer.
1025 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1030 s = talloc_vasprintf_append(s, fmt, ap);
1036 alloc an array, checking for integer overflow in the array size
1038 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1040 if (count >= MAX_TALLOC_SIZE/el_size) {
1043 return talloc_named_const(ctx, el_size * count, name);
1047 alloc an zero array, checking for integer overflow in the array size
1049 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1051 if (count >= MAX_TALLOC_SIZE/el_size) {
1054 return _talloc_zero(ctx, el_size * count, name);
1059 realloc an array, checking for integer overflow in the array size
1061 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1063 if (count >= MAX_TALLOC_SIZE/el_size) {
1066 return _talloc_realloc(ctx, ptr, el_size * count, name);
1070 a function version of talloc_realloc(), so it can be passed as a function pointer
1071 to libraries that want a realloc function (a realloc function encapsulates
1072 all the basic capabilities of an allocation library, which is why this is useful)
1074 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1076 return _talloc_realloc(context, ptr, size, NULL);
1080 static void talloc_autofree(void)
1082 talloc_free(cleanup_context);
1083 cleanup_context = NULL;
1087 return a context which will be auto-freed on exit
1088 this is useful for reducing the noise in leak reports
1090 void *talloc_autofree_context(void)
1092 if (cleanup_context == NULL) {
1093 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1094 atexit(talloc_autofree);
1096 return cleanup_context;
1099 size_t talloc_get_size(const void *context)
1101 struct talloc_chunk *tc;
1103 if (context == NULL)
1106 tc = talloc_chunk_from_ptr(context);