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/
37 #define HAVE_SYS_TYPES_H
43 #ifdef HAVE_SYS_TYPES_H
44 #include <sys/types.h>
63 /* use this to force every realloc to change the pointer, to stress test
64 code that might not cope */
65 #define ALWAYS_REALLOC 0
68 #define MAX_TALLOC_SIZE 0x10000000
69 #define TALLOC_MAGIC 0xe814ec4f
70 #define TALLOC_MAGIC_FREE 0x7faebef3
71 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
73 /* by default we abort when given a bad pointer (such as when talloc_free() is
74 * called on a pointer that came from malloc() */
76 #define TALLOC_ABORT(reason) abort()
79 #ifndef discard_const_p
80 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
81 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
83 # define discard_const_p(type, ptr) ((type *)(ptr))
87 /* this null_context is only used if talloc_enable_leak_report() or
88 talloc_enable_leak_report_full() is called, otherwise it remains
91 static const void *null_context;
92 static void *cleanup_context;
95 struct talloc_reference_handle {
96 struct talloc_reference_handle *next, *prev;
100 typedef int (*talloc_destructor_t)(void *);
102 struct talloc_chunk {
103 struct talloc_chunk *next, *prev;
104 struct talloc_chunk *parent, *child;
105 struct talloc_reference_handle *refs;
107 talloc_destructor_t destructor;
115 /* panic if we get a bad magic value */
116 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
118 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
119 if (tc->u.magic != TALLOC_MAGIC) {
120 if (tc->u.magic == TALLOC_MAGIC_FREE) {
121 TALLOC_ABORT("Bad talloc magic value - double free");
123 TALLOC_ABORT("Bad talloc magic value - unknown value");
130 /* hook into the front of the list */
131 #define _TLIST_ADD(list, p) \
135 (p)->next = (p)->prev = NULL; \
137 (list)->prev = (p); \
138 (p)->next = (list); \
144 /* remove an element from a list - element doesn't have to be in list. */
145 #define _TLIST_REMOVE(list, p) \
147 if ((p) == (list)) { \
148 (list) = (p)->next; \
149 if (list) (list)->prev = NULL; \
151 if ((p)->prev) (p)->prev->next = (p)->next; \
152 if ((p)->next) (p)->next->prev = (p)->prev; \
154 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
159 return the parent chunk of a pointer
161 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
163 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
164 while (tc->prev) tc=tc->prev;
168 void *talloc_parent(const void *ptr)
170 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
171 return (void *)(tc+1);
175 Allocate a bit of memory as a child of an existing pointer
177 void *_talloc(const void *context, size_t size)
179 struct talloc_chunk *tc;
181 if (context == NULL) {
182 context = null_context;
185 if (size >= MAX_TALLOC_SIZE) {
189 tc = malloc(sizeof(*tc)+size);
190 if (tc == NULL) return NULL;
193 tc->u.magic = TALLOC_MAGIC;
194 tc->destructor = NULL;
200 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
205 parent->child->parent = NULL;
208 _TLIST_ADD(parent->child, tc);
210 tc->next = tc->prev = tc->parent = NULL;
213 return (void *)(tc+1);
218 setup a destructor to be called on free of a pointer
219 the destructor should return 0 on success, or -1 on failure.
220 if the destructor fails then the free is failed, and the memory can
221 be continued to be used
223 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
225 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
226 tc->destructor = destructor;
230 increase the reference count on a piece of memory.
232 void talloc_increase_ref_count(const void *ptr)
234 talloc_reference(null_context, ptr);
238 helper for talloc_reference()
240 static int talloc_reference_destructor(void *ptr)
242 struct talloc_reference_handle *handle = ptr;
243 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
244 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
245 if (tc1->destructor != (talloc_destructor_t)-1) {
246 tc1->destructor = NULL;
248 _TLIST_REMOVE(tc2->refs, handle);
254 make a secondary reference to a pointer, hanging off the given context.
255 the pointer remains valid until both the original caller and this given
258 the major use for this is when two different structures need to reference the
259 same underlying data, and you want to be able to free the two instances
260 separately, and in either order
262 void *talloc_reference(const void *context, const void *ptr)
264 struct talloc_chunk *tc;
265 struct talloc_reference_handle *handle;
266 if (ptr == NULL) return NULL;
268 tc = talloc_chunk_from_ptr(ptr);
269 handle = talloc_named_const(context, sizeof(*handle),
270 TALLOC_MAGIC_REFERENCE);
272 if (handle == NULL) return NULL;
274 /* note that we hang the destructor off the handle, not the
275 main context as that allows the caller to still setup their
276 own destructor on the context if they want to */
277 talloc_set_destructor(handle, talloc_reference_destructor);
278 handle->ptr = discard_const_p(void, ptr);
279 _TLIST_ADD(tc->refs, handle);
284 remove a secondary reference to a pointer. This undo's what
285 talloc_reference() has done. The context and pointer arguments
286 must match those given to a talloc_reference()
288 static int talloc_unreference(const void *context, const void *ptr)
290 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
291 struct talloc_reference_handle *h;
293 if (context == NULL) {
294 context = null_context;
297 for (h=tc->refs;h;h=h->next) {
298 struct talloc_chunk *p = talloc_parent_chunk(h);
299 if ((p==NULL && context==NULL) || p+1 == context) break;
305 talloc_set_destructor(h, NULL);
306 _TLIST_REMOVE(tc->refs, h);
312 remove a specific parent context from a pointer. This is a more
313 controlled varient of talloc_free()
315 int talloc_unlink(const void *context, void *ptr)
317 struct talloc_chunk *tc_p, *new_p;
324 if (context == NULL) {
325 context = null_context;
328 if (talloc_unreference(context, ptr) == 0) {
332 if (context == NULL) {
333 if (talloc_parent_chunk(ptr) != NULL) {
337 if (talloc_chunk_from_ptr(context)
338 != talloc_parent_chunk(ptr)) {
343 tc_p = talloc_chunk_from_ptr(ptr);
345 if (tc_p->refs == NULL) {
346 return talloc_free(ptr);
349 new_p = talloc_parent_chunk(tc_p->refs);
351 new_parent = new_p+1;
356 if (talloc_unreference(new_parent, ptr) != 0) {
360 talloc_steal(new_parent, ptr);
366 add a name to an existing pointer - va_list version
368 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
369 PRINTF_ATTRIBUTE(2,0);
371 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
373 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
374 tc->name = talloc_vasprintf(ptr, fmt, ap);
376 talloc_set_name_const(tc->name, ".name");
381 add a name to an existing pointer
383 void talloc_set_name(const void *ptr, const char *fmt, ...)
387 talloc_set_name_v(ptr, fmt, ap);
392 more efficient way to add a name to a pointer - the name must point to a
395 void talloc_set_name_const(const void *ptr, const char *name)
397 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
402 create a named talloc pointer. Any talloc pointer can be named, and
403 talloc_named() operates just like talloc() except that it allows you
406 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
411 ptr = _talloc(context, size);
412 if (ptr == NULL) return NULL;
415 talloc_set_name_v(ptr, fmt, ap);
422 create a named talloc pointer. Any talloc pointer can be named, and
423 talloc_named() operates just like talloc() except that it allows you
426 void *talloc_named_const(const void *context, size_t size, const char *name)
430 ptr = _talloc(context, size);
435 talloc_set_name_const(ptr, name);
441 return the name of a talloc ptr, or "UNNAMED"
443 const char *talloc_get_name(const void *ptr)
445 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
446 if (tc->name == TALLOC_MAGIC_REFERENCE) {
457 check if a pointer has the given name. If it does, return the pointer,
458 otherwise return NULL
460 void *talloc_check_name(const void *ptr, const char *name)
463 if (ptr == NULL) return NULL;
464 pname = talloc_get_name(ptr);
465 if (pname == name || strcmp(pname, name) == 0) {
466 return discard_const_p(void, ptr);
473 this is for compatibility with older versions of talloc
475 void *talloc_init(const char *fmt, ...)
480 ptr = _talloc(NULL, 0);
481 if (ptr == NULL) return NULL;
484 talloc_set_name_v(ptr, fmt, ap);
491 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
492 should probably not be used in new code. It's in here to keep the talloc
493 code consistent across Samba 3 and 4.
495 static void talloc_free_children(void *ptr)
497 struct talloc_chunk *tc;
503 tc = talloc_chunk_from_ptr(ptr);
506 /* we need to work out who will own an abandoned child
507 if it cannot be freed. In priority order, the first
508 choice is owner of any remaining reference to this
509 pointer, the second choice is our parent, and the
510 final choice is the null context. */
511 void *child = tc->child+1;
512 const void *new_parent = null_context;
513 if (tc->child->refs) {
514 struct talloc_chunk *p =
515 talloc_parent_chunk(tc->child->refs);
516 if (p) new_parent = p+1;
518 if (talloc_free(child) == -1) {
519 if (new_parent == null_context) {
520 struct talloc_chunk *p =
521 talloc_parent_chunk(ptr);
522 if (p) new_parent = p+1;
524 talloc_steal(new_parent, child);
530 free a talloc pointer. This also frees all child pointers of this
533 return 0 if the memory is actually freed, otherwise -1. The memory
534 will not be freed if the ref_count is > 1 or the destructor (if
535 any) returns non-zero
537 int talloc_free(void *ptr)
539 struct talloc_chunk *tc;
545 tc = talloc_chunk_from_ptr(ptr);
548 talloc_reference_destructor(tc->refs);
552 if (tc->destructor) {
553 talloc_destructor_t d = tc->destructor;
554 if (d == (talloc_destructor_t)-1) {
557 tc->destructor = (talloc_destructor_t)-1;
562 tc->destructor = NULL;
565 talloc_free_children(ptr);
568 _TLIST_REMOVE(tc->parent->child, tc);
569 if (tc->parent->child) {
570 tc->parent->child->parent = tc->parent;
573 if (tc->prev) tc->prev->next = tc->next;
574 if (tc->next) tc->next->prev = tc->prev;
577 tc->u.magic = TALLOC_MAGIC_FREE;
586 A talloc version of realloc. The context argument is only used if
589 void *_talloc_realloc(const void *context, void *ptr, size_t size,
592 struct talloc_chunk *tc;
595 /* size zero is equivalent to free() */
601 if (size >= MAX_TALLOC_SIZE) {
605 /* realloc(NULL) is equavalent to malloc() */
607 return talloc_named_const(context, size, name);
610 tc = talloc_chunk_from_ptr(ptr);
612 /* don't allow realloc on referenced pointers */
617 /* by resetting magic we catch users of the old memory */
618 tc->u.magic = TALLOC_MAGIC_FREE;
621 new_ptr = malloc(size + sizeof(*tc));
623 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
627 new_ptr = realloc(tc, size + sizeof(*tc));
630 tc->u.magic = TALLOC_MAGIC;
635 tc->u.magic = TALLOC_MAGIC;
637 tc->parent->child = new_ptr;
640 tc->child->parent = new_ptr;
651 talloc_set_name_const(tc+1, name);
653 return (void *)(tc+1);
657 move a lump of memory from one talloc context to another return the
658 ptr on success, or NULL if it could not be transferred.
659 passing NULL as ptr will always return NULL with no side effects.
661 void *talloc_steal(const void *new_ctx, const void *ptr)
663 struct talloc_chunk *tc, *new_tc;
669 if (new_ctx == NULL) {
670 new_ctx = null_context;
673 tc = talloc_chunk_from_ptr(ptr);
675 if (new_ctx == NULL) {
677 _TLIST_REMOVE(tc->parent->child, tc);
678 if (tc->parent->child) {
679 tc->parent->child->parent = tc->parent;
682 if (tc->prev) tc->prev->next = tc->next;
683 if (tc->next) tc->next->prev = tc->prev;
686 tc->parent = tc->next = tc->prev = NULL;
687 return discard_const_p(void, ptr);
690 new_tc = talloc_chunk_from_ptr(new_ctx);
693 return discard_const_p(void, ptr);
697 _TLIST_REMOVE(tc->parent->child, tc);
698 if (tc->parent->child) {
699 tc->parent->child->parent = tc->parent;
702 if (tc->prev) tc->prev->next = tc->next;
703 if (tc->next) tc->next->prev = tc->prev;
707 if (new_tc->child) new_tc->child->parent = NULL;
708 _TLIST_ADD(new_tc->child, tc);
710 return discard_const_p(void, ptr);
714 return the total size of a talloc pool (subtree)
716 off_t talloc_total_size(const void *ptr)
719 struct talloc_chunk *c, *tc;
728 tc = talloc_chunk_from_ptr(ptr);
731 for (c=tc->child;c;c=c->next) {
732 total += talloc_total_size(c+1);
738 return the total number of blocks in a talloc pool (subtree)
740 off_t talloc_total_blocks(const void *ptr)
743 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
746 for (c=tc->child;c;c=c->next) {
747 total += talloc_total_blocks(c+1);
753 return the number of external references to a pointer
755 static int talloc_reference_count(const void *ptr)
757 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
758 struct talloc_reference_handle *h;
761 for (h=tc->refs;h;h=h->next) {
768 report on memory usage by all children of a pointer, giving a full tree view
770 void talloc_report_depth(const void *ptr, FILE *f, int depth)
772 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
774 for (c=tc->child;c;c=c->next) {
775 if (c->name == TALLOC_MAGIC_REFERENCE) {
776 struct talloc_reference_handle *handle = (void *)(c+1);
777 const char *name2 = talloc_get_name(handle->ptr);
778 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
780 const char *name = talloc_get_name(c+1);
781 fprintf(f, "%*s%-30s contains %6lu bytes "
782 "in %3lu blocks (ref %d)\n",
784 (unsigned long)talloc_total_size(c+1),
785 (unsigned long)talloc_total_blocks(c+1),
786 talloc_reference_count(c+1));
787 talloc_report_depth(c+1, f, depth+1);
794 report on memory usage by all children of a pointer, giving a full tree view
796 void talloc_report_full(const void *ptr, FILE *f)
801 if (ptr == NULL) return;
803 fprintf(f, "full talloc report on '%s' "
804 "(total %lu bytes in %lu blocks)\n",
805 talloc_get_name(ptr),
806 (unsigned long)talloc_total_size(ptr),
807 (unsigned long)talloc_total_blocks(ptr));
809 talloc_report_depth(ptr, f, 1);
814 report on memory usage by all children of a pointer
816 void talloc_report(const void *ptr, FILE *f)
818 struct talloc_chunk *c, *tc;
823 if (ptr == NULL) return;
825 fprintf(f, "talloc report on '%s' (total %lu bytes in %lu blocks)\n",
826 talloc_get_name(ptr),
827 (unsigned long)talloc_total_size(ptr),
828 (unsigned long)talloc_total_blocks(ptr));
830 tc = talloc_chunk_from_ptr(ptr);
832 for (c=tc->child;c;c=c->next) {
833 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
834 talloc_get_name(c+1),
835 (unsigned long)talloc_total_size(c+1),
836 (unsigned long)talloc_total_blocks(c+1));
842 report on any memory hanging off the null context
844 static void talloc_report_null(void)
846 if (talloc_total_size(null_context) != 0) {
847 talloc_report(null_context, stderr);
852 report on any memory hanging off the null context
854 static void talloc_report_null_full(void)
856 if (talloc_total_size(null_context) != 0) {
857 talloc_report_full(null_context, stderr);
862 enable tracking of the NULL context
864 void talloc_enable_null_tracking(void)
866 if (null_context == NULL) {
867 null_context = talloc_named_const(NULL, 0, "null_context");
872 enable leak reporting on exit
874 void talloc_enable_leak_report(void)
876 talloc_enable_null_tracking();
877 atexit(talloc_report_null);
881 enable full leak reporting on exit
883 void talloc_enable_leak_report_full(void)
885 talloc_enable_null_tracking();
886 atexit(talloc_report_null_full);
890 talloc and zero memory.
892 void *_talloc_zero(const void *ctx, size_t size, const char *name)
894 void *p = talloc_named_const(ctx, size, name);
897 memset(p, '\0', size);
905 memdup with a talloc.
907 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
909 void *newp = talloc_named_const(t, size, name);
912 memcpy(newp, p, size);
921 char *talloc_strdup(const void *t, const char *p)
927 ret = talloc_memdup(t, p, strlen(p) + 1);
929 talloc_set_name_const(ret, ret);
935 strndup with a talloc
937 char *talloc_strndup(const void *t, const char *p, size_t n)
942 for (len=0; len<n && p[len]; len++) ;
944 ret = _talloc(t, len + 1);
945 if (!ret) { return NULL; }
948 talloc_set_name_const(ret, ret);
954 #define VA_COPY(dest, src) va_copy(dest, src)
955 #elif defined(HAVE___VA_COPY)
956 #define VA_COPY(dest, src) __va_copy(dest, src)
958 #define VA_COPY(dest, src) (dest) = (src)
962 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
970 len = vsnprintf(NULL, 0, fmt, ap2);
972 ret = _talloc(t, len+1);
975 vsnprintf(ret, len+1, fmt, ap2);
976 talloc_set_name_const(ret, ret);
984 Perform string formatting, and return a pointer to newly allocated
985 memory holding the result, inside a memory pool.
987 char *talloc_asprintf(const void *t, const char *fmt, ...)
993 ret = talloc_vasprintf(t, fmt, ap);
1000 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1001 * and return @p s, which may have moved. Good for gradually
1002 * accumulating output into a string buffer.
1005 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1006 PRINTF_ATTRIBUTE(2,0);
1008 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1010 struct talloc_chunk *tc;
1015 return talloc_vasprintf(NULL, fmt, ap);
1018 tc = talloc_chunk_from_ptr(s);
1022 s_len = tc->size - 1;
1023 len = vsnprintf(NULL, 0, fmt, ap2);
1025 s = talloc_realloc(NULL, s, char, s_len + len+1);
1026 if (!s) return NULL;
1030 vsnprintf(s+s_len, len+1, fmt, ap2);
1031 talloc_set_name_const(s, s);
1037 Realloc @p s to append the formatted result of @p fmt and return @p
1038 s, which may have moved. Good for gradually accumulating output
1039 into a string buffer.
1041 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1046 s = talloc_vasprintf_append(s, fmt, ap);
1052 alloc an array, checking for integer overflow in the array size
1054 void *_talloc_array(const void *ctx, size_t el_size, unsigned count,
1057 if (count >= MAX_TALLOC_SIZE/el_size) {
1060 return talloc_named_const(ctx, el_size * count, name);
1064 alloc an zero array, checking for integer overflow in the array size
1066 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count,
1069 if (count >= MAX_TALLOC_SIZE/el_size) {
1072 return _talloc_zero(ctx, el_size * count, name);
1077 realloc an array, checking for integer overflow in the array size
1079 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size,
1080 unsigned count, const char *name)
1082 if (count >= MAX_TALLOC_SIZE/el_size) {
1085 return _talloc_realloc(ctx, ptr, el_size * count, name);
1089 a function version of talloc_realloc(), so it can be passed as a function
1090 pointer to libraries that want a realloc function (a realloc function
1091 encapsulates all the basic capabilities of an allocation library, which is
1094 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1096 return _talloc_realloc(context, ptr, size, NULL);
1100 static void talloc_autofree(void)
1102 talloc_free(cleanup_context);
1103 cleanup_context = NULL;
1107 return a context which will be auto-freed on exit
1108 this is useful for reducing the noise in leak reports
1110 void *talloc_autofree_context(void)
1112 if (cleanup_context == NULL) {
1113 cleanup_context = talloc_named_const(NULL, 0,
1114 "autofree_context");
1115 atexit(talloc_autofree);
1117 return cleanup_context;
1120 size_t talloc_get_size(const void *context)
1122 struct talloc_chunk *tc;
1124 if (context == NULL)
1127 tc = talloc_chunk_from_ptr(context);