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/
29 #if defined(HAVE_CONFIG_H)
33 #define HAVE_SYS_TYPES_H
45 #ifdef HAVE_SYS_TYPES_H
46 #include <sys/types.h>
66 /* use this to force every realloc to change the pointer, to stress test
67 code that might not cope */
68 #define ALWAYS_REALLOC 0
71 #define MAX_TALLOC_SIZE 0x10000000
72 #define TALLOC_MAGIC 0xe814ec4f
73 #define TALLOC_MAGIC_FREE 0x7faebef3
74 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
76 #ifndef discard_const_p
77 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
78 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
80 # define discard_const_p(type, ptr) ((type *)(ptr))
84 /* this null_context is only used if talloc_enable_leak_report() or
85 talloc_enable_leak_report_full() is called, otherwise it remains
88 static const void *null_context;
89 static void *cleanup_context;
92 struct talloc_reference_handle {
93 struct talloc_reference_handle *next, *prev;
97 typedef int (*talloc_destructor_t)(void *);
100 struct talloc_chunk *next, *prev;
101 struct talloc_chunk *parent, *child;
102 struct talloc_reference_handle *refs;
104 talloc_destructor_t destructor;
112 /* panic if we get a bad magic value */
113 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
115 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
116 if (tc->u.magic != TALLOC_MAGIC) {
117 if (tc->u.magic == TALLOC_MAGIC_FREE) {
118 pb_log_fn("Failed: Bad talloc magic value - double free, for name: %s\n",
120 fprintf(stderr, "%s: name: %s\n", __func__, tc->name);
122 assert(0 && "Bad talloc magic value - double free");
124 pb_log_fn("Failed: Bad talloc magic value - unknown value\n");
125 assert(0 && "Bad talloc magic value - unknown value");
133 /* hook into the front of the list */
134 #define _TLIST_ADD(list, p) \
138 (p)->next = (p)->prev = NULL; \
140 (list)->prev = (p); \
141 (p)->next = (list); \
147 /* remove an element from a list - element doesn't have to be in list. */
148 #define _TLIST_REMOVE(list, p) \
150 if ((p) == (list)) { \
151 (list) = (p)->next; \
152 if (list) (list)->prev = NULL; \
154 if ((p)->prev) (p)->prev->next = (p)->next; \
155 if ((p)->next) (p)->next->prev = (p)->prev; \
157 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
162 return the parent chunk of a pointer
164 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
166 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
167 while (tc->prev) tc=tc->prev;
171 void *talloc_parent(const void *ptr)
173 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
174 return (void *)(tc+1);
178 Allocate a bit of memory as a child of an existing pointer
180 void *_talloc(const void *context, size_t size)
182 struct talloc_chunk *tc;
184 if (context == NULL) {
185 context = null_context;
188 if (size >= MAX_TALLOC_SIZE) {
192 tc = malloc(sizeof(*tc)+size);
193 if (tc == NULL) return NULL;
196 tc->u.magic = TALLOC_MAGIC;
197 tc->destructor = NULL;
203 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
208 parent->child->parent = NULL;
211 _TLIST_ADD(parent->child, tc);
213 tc->next = tc->prev = tc->parent = NULL;
216 return (void *)(tc+1);
221 setup a destructor to be called on free of a pointer
222 the destructor should return 0 on success, or -1 on failure.
223 if the destructor fails then the free is failed, and the memory can
224 be continued to be used
226 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
228 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
229 tc->destructor = destructor;
233 increase the reference count on a piece of memory.
235 void talloc_increase_ref_count(const void *ptr)
237 talloc_reference(null_context, ptr);
241 helper for talloc_reference()
243 static int talloc_reference_destructor(void *ptr)
245 struct talloc_reference_handle *handle = ptr;
246 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
247 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
248 if (tc1->destructor != (talloc_destructor_t)-1) {
249 tc1->destructor = NULL;
251 _TLIST_REMOVE(tc2->refs, handle);
257 make a secondary reference to a pointer, hanging off the given context.
258 the pointer remains valid until both the original caller and this given
261 the major use for this is when two different structures need to reference the
262 same underlying data, and you want to be able to free the two instances
263 separately, and in either order
265 void *talloc_reference(const void *context, const void *ptr)
267 struct talloc_chunk *tc;
268 struct talloc_reference_handle *handle;
269 if (ptr == NULL) return NULL;
271 tc = talloc_chunk_from_ptr(ptr);
272 handle = talloc_named_const(context, sizeof(*handle),
273 TALLOC_MAGIC_REFERENCE);
275 if (handle == NULL) return NULL;
277 /* note that we hang the destructor off the handle, not the
278 main context as that allows the caller to still setup their
279 own destructor on the context if they want to */
280 talloc_set_destructor(handle, talloc_reference_destructor);
281 handle->ptr = discard_const_p(void, ptr);
282 _TLIST_ADD(tc->refs, handle);
287 remove a secondary reference to a pointer. This undo's what
288 talloc_reference() has done. The context and pointer arguments
289 must match those given to a talloc_reference()
291 static int talloc_unreference(const void *context, const void *ptr)
293 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
294 struct talloc_reference_handle *h;
296 if (context == NULL) {
297 context = null_context;
300 for (h=tc->refs;h;h=h->next) {
301 struct talloc_chunk *p = talloc_parent_chunk(h);
302 if ((p==NULL && context==NULL) || p+1 == context) break;
308 talloc_set_destructor(h, NULL);
309 _TLIST_REMOVE(tc->refs, h);
315 remove a specific parent context from a pointer. This is a more
316 controlled varient of talloc_free()
318 int talloc_unlink(const void *context, void *ptr)
320 struct talloc_chunk *tc_p, *new_p;
327 if (context == NULL) {
328 context = null_context;
331 if (talloc_unreference(context, ptr) == 0) {
335 if (context == NULL) {
336 if (talloc_parent_chunk(ptr) != NULL) {
340 if (talloc_chunk_from_ptr(context)
341 != talloc_parent_chunk(ptr)) {
346 tc_p = talloc_chunk_from_ptr(ptr);
348 if (tc_p->refs == NULL) {
349 return talloc_free(ptr);
352 new_p = talloc_parent_chunk(tc_p->refs);
354 new_parent = new_p+1;
359 if (talloc_unreference(new_parent, ptr) != 0) {
363 talloc_steal(new_parent, ptr);
369 add a name to an existing pointer - va_list version
371 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
372 PRINTF_ATTRIBUTE(2,0);
374 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
376 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
377 tc->name = talloc_vasprintf(ptr, fmt, ap);
379 talloc_set_name_const(tc->name, ".name");
384 add a name to an existing pointer
386 void talloc_set_name(const void *ptr, const char *fmt, ...)
390 talloc_set_name_v(ptr, fmt, ap);
395 more efficient way to add a name to a pointer - the name must point to a
398 void talloc_set_name_const(const void *ptr, const char *name)
400 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
405 create a named talloc pointer. Any talloc pointer can be named, and
406 talloc_named() operates just like talloc() except that it allows you
409 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
414 ptr = _talloc(context, size);
415 if (ptr == NULL) return NULL;
418 talloc_set_name_v(ptr, fmt, ap);
425 create a named talloc pointer. Any talloc pointer can be named, and
426 talloc_named() operates just like talloc() except that it allows you
429 void *talloc_named_const(const void *context, size_t size, const char *name)
433 ptr = _talloc(context, size);
438 talloc_set_name_const(ptr, name);
444 return the name of a talloc ptr, or "UNNAMED"
446 const char *talloc_get_name(const void *ptr)
448 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
449 if (tc->name == TALLOC_MAGIC_REFERENCE) {
460 check if a pointer has the given name. If it does, return the pointer,
461 otherwise return NULL
463 void *talloc_check_name(const void *ptr, const char *name)
466 if (ptr == NULL) return NULL;
467 pname = talloc_get_name(ptr);
468 if (pname == name || strcmp(pname, name) == 0) {
469 return discard_const_p(void, ptr);
476 this is for compatibility with older versions of talloc
478 void *talloc_init(const char *fmt, ...)
483 ptr = _talloc(NULL, 0);
484 if (ptr == NULL) return NULL;
487 talloc_set_name_v(ptr, fmt, ap);
494 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
495 should probably not be used in new code. It's in here to keep the talloc
496 code consistent across Samba 3 and 4.
498 static void talloc_free_children(void *ptr)
500 struct talloc_chunk *tc;
506 tc = talloc_chunk_from_ptr(ptr);
509 /* we need to work out who will own an abandoned child
510 if it cannot be freed. In priority order, the first
511 choice is owner of any remaining reference to this
512 pointer, the second choice is our parent, and the
513 final choice is the null context. */
514 void *child = tc->child+1;
515 const void *new_parent = null_context;
516 if (tc->child->refs) {
517 struct talloc_chunk *p =
518 talloc_parent_chunk(tc->child->refs);
519 if (p) new_parent = p+1;
521 if (talloc_free(child) == -1) {
522 if (new_parent == null_context) {
523 struct talloc_chunk *p =
524 talloc_parent_chunk(ptr);
525 if (p) new_parent = p+1;
527 talloc_steal(new_parent, child);
533 free a talloc pointer. This also frees all child pointers of this
536 return 0 if the memory is actually freed, otherwise -1. The memory
537 will not be freed if the ref_count is > 1 or the destructor (if
538 any) returns non-zero
540 int talloc_free(void *ptr)
542 struct talloc_chunk *tc;
548 tc = talloc_chunk_from_ptr(ptr);
551 talloc_reference_destructor(tc->refs);
555 if (tc->destructor) {
556 talloc_destructor_t d = tc->destructor;
557 if (d == (talloc_destructor_t)-1) {
560 tc->destructor = (talloc_destructor_t)-1;
565 tc->destructor = NULL;
568 talloc_free_children(ptr);
571 _TLIST_REMOVE(tc->parent->child, tc);
572 if (tc->parent->child) {
573 tc->parent->child->parent = tc->parent;
576 if (tc->prev) tc->prev->next = tc->next;
577 if (tc->next) tc->next->prev = tc->prev;
580 tc->u.magic = TALLOC_MAGIC_FREE;
589 A talloc version of realloc. The context argument is only used if
592 void *_talloc_realloc(const void *context, void *ptr, size_t size,
595 struct talloc_chunk *tc;
598 /* size zero is equivalent to free() */
604 if (size >= MAX_TALLOC_SIZE) {
608 /* realloc(NULL) is equavalent to malloc() */
610 return talloc_named_const(context, size, name);
613 tc = talloc_chunk_from_ptr(ptr);
615 /* don't allow realloc on referenced pointers */
620 /* by resetting magic we catch users of the old memory */
621 tc->u.magic = TALLOC_MAGIC_FREE;
624 new_ptr = malloc(size + sizeof(*tc));
626 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
630 new_ptr = realloc(tc, size + sizeof(*tc));
633 tc->u.magic = TALLOC_MAGIC;
638 tc->u.magic = TALLOC_MAGIC;
640 tc->parent->child = new_ptr;
643 tc->child->parent = new_ptr;
654 talloc_set_name_const(tc+1, name);
656 return (void *)(tc+1);
660 move a lump of memory from one talloc context to another return the
661 ptr on success, or NULL if it could not be transferred.
662 passing NULL as ptr will always return NULL with no side effects.
664 void *talloc_steal(const void *new_ctx, const void *ptr)
666 struct talloc_chunk *tc, *new_tc;
672 if (new_ctx == NULL) {
673 new_ctx = null_context;
676 tc = talloc_chunk_from_ptr(ptr);
678 if (new_ctx == NULL) {
680 _TLIST_REMOVE(tc->parent->child, tc);
681 if (tc->parent->child) {
682 tc->parent->child->parent = tc->parent;
685 if (tc->prev) tc->prev->next = tc->next;
686 if (tc->next) tc->next->prev = tc->prev;
689 tc->parent = tc->next = tc->prev = NULL;
690 return discard_const_p(void, ptr);
693 new_tc = talloc_chunk_from_ptr(new_ctx);
696 return discard_const_p(void, ptr);
700 _TLIST_REMOVE(tc->parent->child, tc);
701 if (tc->parent->child) {
702 tc->parent->child->parent = tc->parent;
705 if (tc->prev) tc->prev->next = tc->next;
706 if (tc->next) tc->next->prev = tc->prev;
710 if (new_tc->child) new_tc->child->parent = NULL;
711 _TLIST_ADD(new_tc->child, tc);
713 return discard_const_p(void, ptr);
717 return the total size of a talloc pool (subtree)
719 off_t talloc_total_size(const void *ptr)
722 struct talloc_chunk *c, *tc;
731 tc = talloc_chunk_from_ptr(ptr);
734 for (c=tc->child;c;c=c->next) {
735 total += talloc_total_size(c+1);
741 return the total number of blocks in a talloc pool (subtree)
743 off_t talloc_total_blocks(const void *ptr)
746 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
749 for (c=tc->child;c;c=c->next) {
750 total += talloc_total_blocks(c+1);
756 return the number of external references to a pointer
758 int talloc_reference_count(const void *ptr)
760 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
761 struct talloc_reference_handle *h;
764 for (h=tc->refs;h;h=h->next) {
771 report on memory usage by all children of a pointer, giving a full tree view
773 void talloc_report_depth(const void *ptr, FILE *f, int depth)
775 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
777 for (c=tc->child;c;c=c->next) {
778 if (c->name == TALLOC_MAGIC_REFERENCE) {
779 struct talloc_reference_handle *handle = (void *)(c+1);
780 const char *name2 = talloc_get_name(handle->ptr);
781 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
783 const char *name = talloc_get_name(c+1);
784 fprintf(f, "%*s%-30s contains %6lu bytes "
785 "in %3lu blocks (ref %d)\n",
787 (unsigned long)talloc_total_size(c+1),
788 (unsigned long)talloc_total_blocks(c+1),
789 talloc_reference_count(c+1));
790 talloc_report_depth(c+1, f, depth+1);
797 report on memory usage by all children of a pointer, giving a full tree view
799 void talloc_report_full(const void *ptr, FILE *f)
804 if (ptr == NULL) return;
806 fprintf(f, "full talloc report on '%s' "
807 "(total %lu bytes in %lu blocks)\n",
808 talloc_get_name(ptr),
809 (unsigned long)talloc_total_size(ptr),
810 (unsigned long)talloc_total_blocks(ptr));
812 talloc_report_depth(ptr, f, 1);
817 report on memory usage by all children of a pointer
819 void talloc_report(const void *ptr, FILE *f)
821 struct talloc_chunk *c, *tc;
826 if (ptr == NULL) return;
828 fprintf(f, "talloc report on '%s' (total %lu bytes in %lu blocks)\n",
829 talloc_get_name(ptr),
830 (unsigned long)talloc_total_size(ptr),
831 (unsigned long)talloc_total_blocks(ptr));
833 tc = talloc_chunk_from_ptr(ptr);
835 for (c=tc->child;c;c=c->next) {
836 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
837 talloc_get_name(c+1),
838 (unsigned long)talloc_total_size(c+1),
839 (unsigned long)talloc_total_blocks(c+1));
845 report on any memory hanging off the null context
847 static void talloc_report_null(void)
849 if (talloc_total_size(null_context) != 0) {
850 talloc_report(null_context, stderr);
855 report on any memory hanging off the null context
857 static void talloc_report_null_full(void)
859 if (talloc_total_size(null_context) != 0) {
860 talloc_report_full(null_context, stderr);
865 enable tracking of the NULL context
867 void talloc_enable_null_tracking(void)
869 if (null_context == NULL) {
870 null_context = talloc_named_const(NULL, 0, "null_context");
875 enable leak reporting on exit
877 void talloc_enable_leak_report(void)
879 talloc_enable_null_tracking();
880 atexit(talloc_report_null);
884 enable full leak reporting on exit
886 void talloc_enable_leak_report_full(void)
888 talloc_enable_null_tracking();
889 atexit(talloc_report_null_full);
893 talloc and zero memory.
895 void *_talloc_zero(const void *ctx, size_t size, const char *name)
897 void *p = talloc_named_const(ctx, size, name);
900 memset(p, '\0', size);
908 memdup with a talloc.
910 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
912 void *newp = talloc_named_const(t, size, name);
915 memcpy(newp, p, size);
924 char *talloc_strdup(const void *t, const char *p)
930 ret = talloc_memdup(t, p, strlen(p) + 1);
932 talloc_set_name_const(ret, ret);
938 strndup with a talloc
940 char *talloc_strndup(const void *t, const char *p, size_t n)
945 for (len=0; len<n && p[len]; len++) ;
947 ret = _talloc(t, len + 1);
948 if (!ret) { return NULL; }
951 talloc_set_name_const(ret, ret);
957 #define VA_COPY(dest, src) va_copy(dest, src)
958 #elif defined(HAVE___VA_COPY)
959 #define VA_COPY(dest, src) __va_copy(dest, src)
961 #define VA_COPY(dest, src) (dest) = (src)
965 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
973 len = vsnprintf(NULL, 0, fmt, ap2);
975 ret = _talloc(t, len+1);
978 vsnprintf(ret, len+1, fmt, ap2);
979 talloc_set_name_const(ret, ret);
988 Perform string formatting, and return a pointer to newly allocated
989 memory holding the result, inside a memory pool.
991 char *talloc_asprintf(const void *t, const char *fmt, ...)
997 ret = talloc_vasprintf(t, fmt, ap);
1004 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1005 * and return @p s, which may have moved. Good for gradually
1006 * accumulating output into a string buffer.
1009 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1010 PRINTF_ATTRIBUTE(2,0);
1012 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1014 struct talloc_chunk *tc;
1019 return talloc_vasprintf(NULL, fmt, ap);
1022 tc = talloc_chunk_from_ptr(s);
1026 s_len = tc->size - 1;
1027 len = vsnprintf(NULL, 0, fmt, ap2);
1029 s = talloc_realloc(NULL, s, char, s_len + len+1);
1035 vsnprintf(s+s_len, len+1, fmt, ap2);
1036 talloc_set_name_const(s, s);
1044 Realloc @p s to append the formatted result of @p fmt and return @p
1045 s, which may have moved. Good for gradually accumulating output
1046 into a string buffer.
1048 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1053 s = talloc_vasprintf_append(s, fmt, ap);
1059 alloc an array, checking for integer overflow in the array size
1061 void *_talloc_array(const void *ctx, size_t el_size, unsigned count,
1064 if (count >= MAX_TALLOC_SIZE/el_size) {
1067 return talloc_named_const(ctx, el_size * count, name);
1071 alloc an zero array, checking for integer overflow in the array size
1073 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count,
1076 if (count >= MAX_TALLOC_SIZE/el_size) {
1079 return _talloc_zero(ctx, el_size * count, name);
1084 realloc an array, checking for integer overflow in the array size
1086 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size,
1087 unsigned count, const char *name)
1089 if (count >= MAX_TALLOC_SIZE/el_size) {
1092 return _talloc_realloc(ctx, ptr, el_size * count, name);
1096 a function version of talloc_realloc(), so it can be passed as a function
1097 pointer to libraries that want a realloc function (a realloc function
1098 encapsulates all the basic capabilities of an allocation library, which is
1101 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1103 return _talloc_realloc(context, ptr, size, NULL);
1107 static void talloc_autofree(void)
1109 talloc_free(cleanup_context);
1110 cleanup_context = NULL;
1114 return a context which will be auto-freed on exit
1115 this is useful for reducing the noise in leak reports
1117 void *talloc_autofree_context(void)
1119 if (cleanup_context == NULL) {
1120 cleanup_context = talloc_named_const(NULL, 0,
1121 "autofree_context");
1122 atexit(talloc_autofree);
1124 return cleanup_context;
1127 size_t talloc_get_size(const void *context)
1129 struct talloc_chunk *tc;
1131 if (context == NULL)
1134 tc = talloc_chunk_from_ptr(context);