input: fix possible crash in printing key combo names
[mplayer.git] / talloc.c
blob87842c5acdd71a07058786099b2892589e56c9b9
1 /*
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
9 Copyright (C) Stefan Metzmacher 2006
11 ** NOTE! The following LGPL license applies to the talloc
12 ** library. This does NOT imply that all of Samba is released
13 ** under the LGPL
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 3 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, see <http://www.gnu.org/licenses/>.
30 inspired by http://swapped.cc/halloc/
33 // Hardcode these for MPlayer assuming a working system.
34 // Original used autoconf detection with workarounds for broken systems.
35 #define HAVE_VA_COPY
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <stdint.h>
40 #include <string.h>
41 #include <stdbool.h>
42 #define MIN(a,b) ((a)<(b)?(a):(b))
43 #define strnlen rep_strnlen
44 static size_t rep_strnlen(const char *s, size_t max)
46 size_t len;
48 for (len = 0; len < max; len++) {
49 if (s[len] == '\0') {
50 break;
53 return len;
58 #ifdef _SAMBA_BUILD_
59 #include "version.h"
60 #if (SAMBA_VERSION_MAJOR<4)
61 #include "includes.h"
62 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
63 * we trust ourselves... */
64 #ifdef malloc
65 #undef malloc
66 #endif
67 #ifdef realloc
68 #undef realloc
69 #endif
70 #define _TALLOC_SAMBA3
71 #endif /* (SAMBA_VERSION_MAJOR<4) */
72 #endif /* _SAMBA_BUILD_ */
74 #ifndef _TALLOC_SAMBA3
75 // Workarounds for missing standard features, not used in MPlayer
76 // #include "replace.h"
77 #include "talloc.h"
78 #endif /* not _TALLOC_SAMBA3 */
80 /* use this to force every realloc to change the pointer, to stress test
81 code that might not cope */
82 #define ALWAYS_REALLOC 0
85 #define MAX_TALLOC_SIZE 0x10000000
86 #define TALLOC_MAGIC 0xe814ec70
87 #define TALLOC_FLAG_FREE 0x01
88 #define TALLOC_FLAG_LOOP 0x02
89 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
90 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
91 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
93 /* by default we abort when given a bad pointer (such as when talloc_free() is called
94 on a pointer that came from malloc() */
95 #ifndef TALLOC_ABORT
96 #define TALLOC_ABORT(reason) abort()
97 #endif
99 #ifndef discard_const_p
100 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
101 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
102 #else
103 # define discard_const_p(type, ptr) ((type *)(ptr))
104 #endif
105 #endif
107 /* these macros gain us a few percent of speed on gcc */
108 #if (__GNUC__ >= 3)
109 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
110 as its first argument */
111 #ifndef likely
112 #define likely(x) __builtin_expect(!!(x), 1)
113 #endif
114 #ifndef unlikely
115 #define unlikely(x) __builtin_expect(!!(x), 0)
116 #endif
117 #else
118 #ifndef likely
119 #define likely(x) (x)
120 #endif
121 #ifndef unlikely
122 #define unlikely(x) (x)
123 #endif
124 #endif
126 /* this null_context is only used if talloc_enable_leak_report() or
127 talloc_enable_leak_report_full() is called, otherwise it remains
128 NULL
130 static void *null_context;
131 static void *autofree_context;
133 struct talloc_reference_handle {
134 struct talloc_reference_handle *next, *prev;
135 void *ptr;
138 typedef int (*talloc_destructor_t)(void *);
140 struct talloc_chunk {
141 struct talloc_chunk *next, *prev;
142 struct talloc_chunk *parent, *child;
143 struct talloc_reference_handle *refs;
144 talloc_destructor_t destructor;
145 const char *name;
146 size_t size;
147 unsigned flags;
150 * "pool" has dual use:
152 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
153 * marks the end of the currently allocated area.
155 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
156 * is a pointer to the struct talloc_chunk of the pool that it was
157 * allocated from. This way children can quickly find the pool to chew
158 * from.
160 void *pool;
163 /* 16 byte alignment seems to keep everyone happy */
164 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
165 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
167 static void talloc_abort_double_free(void)
169 TALLOC_ABORT("Bad talloc magic value - double free");
172 static void talloc_abort_unknown_value(void)
174 TALLOC_ABORT("Bad talloc magic value - unknown value");
177 /* panic if we get a bad magic value */
178 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
180 const char *pp = (const char *)ptr;
181 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
182 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
183 if (tc->flags & TALLOC_FLAG_FREE) {
184 talloc_abort_double_free();
185 } else {
186 talloc_abort_unknown_value();
189 return tc;
192 /* hook into the front of the list */
193 #define _TLIST_ADD(list, p) \
194 do { \
195 if (!(list)) { \
196 (list) = (p); \
197 (p)->next = (p)->prev = NULL; \
198 } else { \
199 (list)->prev = (p); \
200 (p)->next = (list); \
201 (p)->prev = NULL; \
202 (list) = (p); \
204 } while (0)
206 /* remove an element from a list - element doesn't have to be in list. */
207 #define _TLIST_REMOVE(list, p) \
208 do { \
209 if ((p) == (list)) { \
210 (list) = (p)->next; \
211 if (list) (list)->prev = NULL; \
212 } else { \
213 if ((p)->prev) (p)->prev->next = (p)->next; \
214 if ((p)->next) (p)->next->prev = (p)->prev; \
216 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
217 } while (0)
221 return the parent chunk of a pointer
223 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
225 struct talloc_chunk *tc;
227 if (unlikely(ptr == NULL)) {
228 return NULL;
231 tc = talloc_chunk_from_ptr(ptr);
232 while (tc->prev) tc=tc->prev;
234 return tc->parent;
237 void *talloc_parent(const void *ptr)
239 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
240 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
244 find parents name
246 const char *talloc_parent_name(const void *ptr)
248 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
249 return tc? tc->name : NULL;
253 A pool carries an in-pool object count count in the first 16 bytes.
254 bytes. This is done to support talloc_steal() to a parent outside of the
255 pool. The count includes the pool itself, so a talloc_free() on a pool will
256 only destroy the pool if the count has dropped to zero. A talloc_free() of a
257 pool member will reduce the count, and eventually also call free(3) on the
258 pool memory.
260 The object count is not put into "struct talloc_chunk" because it is only
261 relevant for talloc pools and the alignment to 16 bytes would increase the
262 memory footprint of each talloc chunk by those 16 bytes.
265 #define TALLOC_POOL_HDR_SIZE 16
267 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
269 return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
273 Allocate from a pool
276 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
277 size_t size)
279 struct talloc_chunk *pool_ctx = NULL;
280 size_t space_left;
281 struct talloc_chunk *result;
282 size_t chunk_size;
284 if (parent == NULL) {
285 return NULL;
288 if (parent->flags & TALLOC_FLAG_POOL) {
289 pool_ctx = parent;
291 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
292 pool_ctx = (struct talloc_chunk *)parent->pool;
295 if (pool_ctx == NULL) {
296 return NULL;
299 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
300 - ((char *)pool_ctx->pool);
303 * Align size to 16 bytes
305 chunk_size = ((size + 15) & ~15);
307 if (space_left < chunk_size) {
308 return NULL;
311 result = (struct talloc_chunk *)pool_ctx->pool;
313 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
314 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
315 #endif
317 pool_ctx->pool = (void *)((char *)result + chunk_size);
319 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
320 result->pool = pool_ctx;
322 *talloc_pool_objectcount(pool_ctx) += 1;
324 return result;
328 Allocate a bit of memory as a child of an existing pointer
330 static inline void *__talloc(const void *context, size_t size)
332 struct talloc_chunk *tc = NULL;
334 if (unlikely(context == NULL)) {
335 context = null_context;
338 if (unlikely(size >= MAX_TALLOC_SIZE)) {
339 abort(); // return NULL;
342 if (context != NULL) {
343 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
344 TC_HDR_SIZE+size);
347 if (tc == NULL) {
348 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
349 if (unlikely(tc == NULL)) abort(); // return NULL;
350 tc->flags = TALLOC_MAGIC;
351 tc->pool = NULL;
354 tc->size = size;
355 tc->destructor = NULL;
356 tc->child = NULL;
357 tc->name = NULL;
358 tc->refs = NULL;
360 if (likely(context)) {
361 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
363 if (parent->child) {
364 parent->child->parent = NULL;
365 tc->next = parent->child;
366 tc->next->prev = tc;
367 } else {
368 tc->next = NULL;
370 tc->parent = parent;
371 tc->prev = NULL;
372 parent->child = tc;
373 } else {
374 tc->next = tc->prev = tc->parent = NULL;
377 return TC_PTR_FROM_CHUNK(tc);
381 * Create a talloc pool
384 void *talloc_pool(const void *context, size_t size)
386 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
387 struct talloc_chunk *tc;
389 if (unlikely(result == NULL)) {
390 return NULL;
393 tc = talloc_chunk_from_ptr(result);
395 tc->flags |= TALLOC_FLAG_POOL;
396 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
398 *talloc_pool_objectcount(tc) = 1;
400 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
401 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
402 #endif
404 return result;
408 setup a destructor to be called on free of a pointer
409 the destructor should return 0 on success, or -1 on failure.
410 if the destructor fails then the free is failed, and the memory can
411 be continued to be used
413 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
415 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
416 tc->destructor = destructor;
420 increase the reference count on a piece of memory.
422 int talloc_increase_ref_count(const void *ptr)
424 if (unlikely(!talloc_reference(null_context, ptr))) {
425 return -1;
427 return 0;
431 helper for talloc_reference()
433 this is referenced by a function pointer and should not be inline
435 static int talloc_reference_destructor(void *ptr)
437 struct talloc_reference_handle *handle = ptr;
438 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
439 _TLIST_REMOVE(ptr_tc->refs, handle);
440 return 0;
444 more efficient way to add a name to a pointer - the name must point to a
445 true string constant
447 static inline void _talloc_set_name_const(const void *ptr, const char *name)
449 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
450 tc->name = name;
454 internal talloc_named_const()
456 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
458 void *ptr;
460 ptr = __talloc(context, size);
461 if (unlikely(ptr == NULL)) {
462 return NULL;
465 _talloc_set_name_const(ptr, name);
467 return ptr;
471 make a secondary reference to a pointer, hanging off the given context.
472 the pointer remains valid until both the original caller and this given
473 context are freed.
475 the major use for this is when two different structures need to reference the
476 same underlying data, and you want to be able to free the two instances separately,
477 and in either order
479 void *_talloc_reference(const void *context, const void *ptr)
481 struct talloc_chunk *tc;
482 struct talloc_reference_handle *handle;
483 if (unlikely(ptr == NULL)) return NULL;
485 tc = talloc_chunk_from_ptr(ptr);
486 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
487 sizeof(struct talloc_reference_handle),
488 TALLOC_MAGIC_REFERENCE);
489 if (unlikely(handle == NULL)) return NULL;
491 /* note that we hang the destructor off the handle, not the
492 main context as that allows the caller to still setup their
493 own destructor on the context if they want to */
494 talloc_set_destructor(handle, talloc_reference_destructor);
495 handle->ptr = discard_const_p(void, ptr);
496 _TLIST_ADD(tc->refs, handle);
497 return handle->ptr;
502 internal talloc_free call
504 static inline int _talloc_free(void *ptr)
506 struct talloc_chunk *tc;
508 if (unlikely(ptr == NULL)) {
509 return -1;
512 tc = talloc_chunk_from_ptr(ptr);
514 if (unlikely(tc->refs)) {
515 int is_child;
516 /* check this is a reference from a child or grantchild
517 * back to it's parent or grantparent
519 * in that case we need to remove the reference and
520 * call another instance of talloc_free() on the current
521 * pointer.
523 is_child = talloc_is_parent(tc->refs, ptr);
524 _talloc_free(tc->refs);
525 if (is_child) {
526 return _talloc_free(ptr);
528 return -1;
531 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
532 /* we have a free loop - stop looping */
533 return 0;
536 if (unlikely(tc->destructor)) {
537 talloc_destructor_t d = tc->destructor;
538 if (d == (talloc_destructor_t)-1) {
539 return -1;
541 tc->destructor = (talloc_destructor_t)-1;
542 if (d(ptr) == -1) {
543 tc->destructor = d;
544 return -1;
546 tc->destructor = NULL;
549 if (tc->parent) {
550 _TLIST_REMOVE(tc->parent->child, tc);
551 if (tc->parent->child) {
552 tc->parent->child->parent = tc->parent;
554 } else {
555 if (tc->prev) tc->prev->next = tc->next;
556 if (tc->next) tc->next->prev = tc->prev;
559 tc->flags |= TALLOC_FLAG_LOOP;
561 while (tc->child) {
562 /* we need to work out who will own an abandoned child
563 if it cannot be freed. In priority order, the first
564 choice is owner of any remaining reference to this
565 pointer, the second choice is our parent, and the
566 final choice is the null context. */
567 void *child = TC_PTR_FROM_CHUNK(tc->child);
568 const void *new_parent = null_context;
569 if (unlikely(tc->child->refs)) {
570 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
571 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
573 if (unlikely(_talloc_free(child) == -1)) {
574 if (new_parent == null_context) {
575 struct talloc_chunk *p = talloc_parent_chunk(ptr);
576 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
578 talloc_steal(new_parent, child);
582 tc->flags |= TALLOC_FLAG_FREE;
584 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
585 struct talloc_chunk *pool;
586 unsigned int *pool_object_count;
588 pool = (tc->flags & TALLOC_FLAG_POOL)
589 ? tc : (struct talloc_chunk *)tc->pool;
591 pool_object_count = talloc_pool_objectcount(pool);
593 if (*pool_object_count == 0) {
594 TALLOC_ABORT("Pool object count zero!");
597 *pool_object_count -= 1;
599 if (*pool_object_count == 0) {
600 free(pool);
603 else {
604 free(tc);
606 return 0;
610 move a lump of memory from one talloc context to another return the
611 ptr on success, or NULL if it could not be transferred.
612 passing NULL as ptr will always return NULL with no side effects.
614 void *_talloc_steal(const void *new_ctx, const void *ptr)
616 struct talloc_chunk *tc, *new_tc;
618 if (unlikely(!ptr)) {
619 return NULL;
622 if (unlikely(new_ctx == NULL)) {
623 new_ctx = null_context;
626 tc = talloc_chunk_from_ptr(ptr);
628 if (unlikely(new_ctx == NULL)) {
629 if (tc->parent) {
630 _TLIST_REMOVE(tc->parent->child, tc);
631 if (tc->parent->child) {
632 tc->parent->child->parent = tc->parent;
634 } else {
635 if (tc->prev) tc->prev->next = tc->next;
636 if (tc->next) tc->next->prev = tc->prev;
639 tc->parent = tc->next = tc->prev = NULL;
640 return discard_const_p(void, ptr);
643 new_tc = talloc_chunk_from_ptr(new_ctx);
645 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
646 return discard_const_p(void, ptr);
649 if (tc->parent) {
650 _TLIST_REMOVE(tc->parent->child, tc);
651 if (tc->parent->child) {
652 tc->parent->child->parent = tc->parent;
654 } else {
655 if (tc->prev) tc->prev->next = tc->next;
656 if (tc->next) tc->next->prev = tc->prev;
659 tc->parent = new_tc;
660 if (new_tc->child) new_tc->child->parent = NULL;
661 _TLIST_ADD(new_tc->child, tc);
663 return discard_const_p(void, ptr);
669 remove a secondary reference to a pointer. This undo's what
670 talloc_reference() has done. The context and pointer arguments
671 must match those given to a talloc_reference()
673 static inline int talloc_unreference(const void *context, const void *ptr)
675 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
676 struct talloc_reference_handle *h;
678 if (unlikely(context == NULL)) {
679 context = null_context;
682 for (h=tc->refs;h;h=h->next) {
683 struct talloc_chunk *p = talloc_parent_chunk(h);
684 if (p == NULL) {
685 if (context == NULL) break;
686 } else if (TC_PTR_FROM_CHUNK(p) == context) {
687 break;
690 if (h == NULL) {
691 return -1;
694 return _talloc_free(h);
698 remove a specific parent context from a pointer. This is a more
699 controlled varient of talloc_free()
701 int talloc_unlink(const void *context, void *ptr)
703 struct talloc_chunk *tc_p, *new_p;
704 void *new_parent;
706 if (ptr == NULL) {
707 return -1;
710 if (context == NULL) {
711 context = null_context;
714 if (talloc_unreference(context, ptr) == 0) {
715 return 0;
718 if (context == NULL) {
719 if (talloc_parent_chunk(ptr) != NULL) {
720 return -1;
722 } else {
723 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
724 return -1;
728 tc_p = talloc_chunk_from_ptr(ptr);
730 if (tc_p->refs == NULL) {
731 return _talloc_free(ptr);
734 new_p = talloc_parent_chunk(tc_p->refs);
735 if (new_p) {
736 new_parent = TC_PTR_FROM_CHUNK(new_p);
737 } else {
738 new_parent = NULL;
741 if (talloc_unreference(new_parent, ptr) != 0) {
742 return -1;
745 talloc_steal(new_parent, ptr);
747 return 0;
751 add a name to an existing pointer - va_list version
753 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
755 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
757 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
758 tc->name = talloc_vasprintf(ptr, fmt, ap);
759 if (likely(tc->name)) {
760 _talloc_set_name_const(tc->name, ".name");
762 return tc->name;
766 add a name to an existing pointer
768 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
770 const char *name;
771 va_list ap;
772 va_start(ap, fmt);
773 name = talloc_set_name_v(ptr, fmt, ap);
774 va_end(ap);
775 return name;
780 create a named talloc pointer. Any talloc pointer can be named, and
781 talloc_named() operates just like talloc() except that it allows you
782 to name the pointer.
784 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
786 va_list ap;
787 void *ptr;
788 const char *name;
790 ptr = __talloc(context, size);
791 if (unlikely(ptr == NULL)) return NULL;
793 va_start(ap, fmt);
794 name = talloc_set_name_v(ptr, fmt, ap);
795 va_end(ap);
797 if (unlikely(name == NULL)) {
798 _talloc_free(ptr);
799 return NULL;
802 return ptr;
806 return the name of a talloc ptr, or "UNNAMED"
808 const char *talloc_get_name(const void *ptr)
810 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
811 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
812 return ".reference";
814 if (likely(tc->name)) {
815 return tc->name;
817 return "UNNAMED";
822 check if a pointer has the given name. If it does, return the pointer,
823 otherwise return NULL
825 void *talloc_check_name(const void *ptr, const char *name)
827 const char *pname;
828 if (unlikely(ptr == NULL)) return NULL;
829 pname = talloc_get_name(ptr);
830 if (likely(pname == name || strcmp(pname, name) == 0)) {
831 return discard_const_p(void, ptr);
833 return NULL;
838 this is for compatibility with older versions of talloc
840 void *talloc_init(const char *fmt, ...)
842 va_list ap;
843 void *ptr;
844 const char *name;
847 * samba3 expects talloc_report_depth_cb(NULL, ...)
848 * reports all talloc'ed memory, so we need to enable
849 * null_tracking
851 talloc_enable_null_tracking();
853 ptr = __talloc(NULL, 0);
854 if (unlikely(ptr == NULL)) return NULL;
856 va_start(ap, fmt);
857 name = talloc_set_name_v(ptr, fmt, ap);
858 va_end(ap);
860 if (unlikely(name == NULL)) {
861 _talloc_free(ptr);
862 return NULL;
865 return ptr;
869 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
870 should probably not be used in new code. It's in here to keep the talloc
871 code consistent across Samba 3 and 4.
873 void talloc_free_children(void *ptr)
875 struct talloc_chunk *tc;
877 if (unlikely(ptr == NULL)) {
878 return;
881 tc = talloc_chunk_from_ptr(ptr);
883 while (tc->child) {
884 /* we need to work out who will own an abandoned child
885 if it cannot be freed. In priority order, the first
886 choice is owner of any remaining reference to this
887 pointer, the second choice is our parent, and the
888 final choice is the null context. */
889 void *child = TC_PTR_FROM_CHUNK(tc->child);
890 const void *new_parent = null_context;
891 if (unlikely(tc->child->refs)) {
892 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
893 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
895 if (unlikely(_talloc_free(child) == -1)) {
896 if (new_parent == null_context) {
897 struct talloc_chunk *p = talloc_parent_chunk(ptr);
898 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
900 talloc_steal(new_parent, child);
904 if ((tc->flags & TALLOC_FLAG_POOL)
905 && (*talloc_pool_objectcount(tc) == 1)) {
906 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
907 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
908 VALGRIND_MAKE_MEM_NOACCESS(
909 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
910 #endif
915 Allocate a bit of memory as a child of an existing pointer
917 void *_talloc(const void *context, size_t size)
919 return __talloc(context, size);
923 externally callable talloc_set_name_const()
925 void talloc_set_name_const(const void *ptr, const char *name)
927 _talloc_set_name_const(ptr, name);
931 create a named talloc pointer. Any talloc pointer can be named, and
932 talloc_named() operates just like talloc() except that it allows you
933 to name the pointer.
935 void *talloc_named_const(const void *context, size_t size, const char *name)
937 return _talloc_named_const(context, size, name);
941 free a talloc pointer. This also frees all child pointers of this
942 pointer recursively
944 return 0 if the memory is actually freed, otherwise -1. The memory
945 will not be freed if the ref_count is > 1 or the destructor (if
946 any) returns non-zero
948 int talloc_free(void *ptr)
950 return _talloc_free(ptr);
956 A talloc version of realloc. The context argument is only used if
957 ptr is NULL
959 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
961 struct talloc_chunk *tc;
962 void *new_ptr;
963 bool malloced = false;
965 /* size zero is equivalent to free() */
966 if (unlikely(size == 0)) {
967 _talloc_free(ptr);
968 return NULL;
971 if (unlikely(size >= MAX_TALLOC_SIZE)) {
972 abort(); // return NULL;
975 /* realloc(NULL) is equivalent to malloc() */
976 if (ptr == NULL) {
977 return _talloc_named_const(context, size, name);
980 tc = talloc_chunk_from_ptr(ptr);
982 /* don't allow realloc on referenced pointers */
983 if (unlikely(tc->refs)) {
984 abort(); // return NULL;
987 /* don't shrink if we have less than 1k to gain */
988 if ((size < tc->size) && ((tc->size - size) < 1024)) {
989 tc->size = size;
990 return ptr;
993 /* by resetting magic we catch users of the old memory */
994 tc->flags |= TALLOC_FLAG_FREE;
996 #if ALWAYS_REALLOC
997 new_ptr = malloc(size + TC_HDR_SIZE);
998 if (new_ptr) {
999 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1000 free(tc);
1002 #else
1003 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1005 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1006 *talloc_pool_objectcount((struct talloc_chunk *)
1007 (tc->pool)) -= 1;
1009 if (new_ptr == NULL) {
1010 new_ptr = malloc(TC_HDR_SIZE+size);
1011 malloced = true;
1014 if (new_ptr) {
1015 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1018 else {
1019 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1021 #endif
1022 if (unlikely(!new_ptr)) {
1023 tc->flags &= ~TALLOC_FLAG_FREE;
1024 abort(); // return NULL;
1027 tc = (struct talloc_chunk *)new_ptr;
1028 tc->flags &= ~TALLOC_FLAG_FREE;
1029 if (malloced) {
1030 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1032 if (tc->parent) {
1033 tc->parent->child = tc;
1035 if (tc->child) {
1036 tc->child->parent = tc;
1039 if (tc->prev) {
1040 tc->prev->next = tc;
1042 if (tc->next) {
1043 tc->next->prev = tc;
1046 tc->size = size;
1047 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1049 return TC_PTR_FROM_CHUNK(tc);
1053 a wrapper around talloc_steal() for situations where you are moving a pointer
1054 between two structures, and want the old pointer to be set to NULL
1056 void *_talloc_move(const void *new_ctx, const void *_pptr)
1058 const void **pptr = discard_const_p(const void *,_pptr);
1059 void *ret = _talloc_steal(new_ctx, *pptr);
1060 (*pptr) = NULL;
1061 return ret;
1065 return the total size of a talloc pool (subtree)
1067 size_t talloc_total_size(const void *ptr)
1069 size_t total = 0;
1070 struct talloc_chunk *c, *tc;
1072 if (ptr == NULL) {
1073 ptr = null_context;
1075 if (ptr == NULL) {
1076 return 0;
1079 tc = talloc_chunk_from_ptr(ptr);
1081 if (tc->flags & TALLOC_FLAG_LOOP) {
1082 return 0;
1085 tc->flags |= TALLOC_FLAG_LOOP;
1087 total = tc->size;
1088 for (c=tc->child;c;c=c->next) {
1089 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1092 tc->flags &= ~TALLOC_FLAG_LOOP;
1094 return total;
1098 return the total number of blocks in a talloc pool (subtree)
1100 size_t talloc_total_blocks(const void *ptr)
1102 size_t total = 0;
1103 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1105 if (tc->flags & TALLOC_FLAG_LOOP) {
1106 return 0;
1109 tc->flags |= TALLOC_FLAG_LOOP;
1111 total++;
1112 for (c=tc->child;c;c=c->next) {
1113 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1116 tc->flags &= ~TALLOC_FLAG_LOOP;
1118 return total;
1122 return the number of external references to a pointer
1124 size_t talloc_reference_count(const void *ptr)
1126 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1127 struct talloc_reference_handle *h;
1128 size_t ret = 0;
1130 for (h=tc->refs;h;h=h->next) {
1131 ret++;
1133 return ret;
1137 report on memory usage by all children of a pointer, giving a full tree view
1139 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1140 void (*callback)(const void *ptr,
1141 int depth, int max_depth,
1142 int is_ref,
1143 void *private_data),
1144 void *private_data)
1146 struct talloc_chunk *c, *tc;
1148 if (ptr == NULL) {
1149 ptr = null_context;
1151 if (ptr == NULL) return;
1153 tc = talloc_chunk_from_ptr(ptr);
1155 if (tc->flags & TALLOC_FLAG_LOOP) {
1156 return;
1159 callback(ptr, depth, max_depth, 0, private_data);
1161 if (max_depth >= 0 && depth >= max_depth) {
1162 return;
1165 tc->flags |= TALLOC_FLAG_LOOP;
1166 for (c=tc->child;c;c=c->next) {
1167 if (c->name == TALLOC_MAGIC_REFERENCE) {
1168 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1169 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1170 } else {
1171 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1174 tc->flags &= ~TALLOC_FLAG_LOOP;
1177 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1179 const char *name = talloc_get_name(ptr);
1180 FILE *f = (FILE *)_f;
1182 if (is_ref) {
1183 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1184 return;
1187 if (depth == 0) {
1188 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1189 (max_depth < 0 ? "full " :""), name,
1190 (unsigned long)talloc_total_size(ptr),
1191 (unsigned long)talloc_total_blocks(ptr));
1192 return;
1195 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1196 depth*4, "",
1197 name,
1198 (unsigned long)talloc_total_size(ptr),
1199 (unsigned long)talloc_total_blocks(ptr),
1200 (int)talloc_reference_count(ptr), ptr);
1202 #if 0
1203 fprintf(f, "content: ");
1204 if (talloc_total_size(ptr)) {
1205 int tot = talloc_total_size(ptr);
1206 int i;
1208 for (i = 0; i < tot; i++) {
1209 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1210 fprintf(f, "%c", ((char *)ptr)[i]);
1211 } else {
1212 fprintf(f, "~%02x", ((char *)ptr)[i]);
1216 fprintf(f, "\n");
1217 #endif
1221 report on memory usage by all children of a pointer, giving a full tree view
1223 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1225 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1226 fflush(f);
1230 report on memory usage by all children of a pointer, giving a full tree view
1232 void talloc_report_full(const void *ptr, FILE *f)
1234 talloc_report_depth_file(ptr, 0, -1, f);
1238 report on memory usage by all children of a pointer
1240 void talloc_report(const void *ptr, FILE *f)
1242 talloc_report_depth_file(ptr, 0, 1, f);
1246 report on any memory hanging off the null context
1248 static void talloc_report_null(void)
1250 if (talloc_total_size(null_context) != 0) {
1251 talloc_report(null_context, stderr);
1256 report on any memory hanging off the null context
1258 static void talloc_report_null_full(void)
1260 if (talloc_total_size(null_context) != 0) {
1261 talloc_report_full(null_context, stderr);
1266 enable tracking of the NULL context
1268 void talloc_enable_null_tracking(void)
1270 if (null_context == NULL) {
1271 null_context = _talloc_named_const(NULL, 0, "null_context");
1276 disable tracking of the NULL context
1278 void talloc_disable_null_tracking(void)
1280 _talloc_free(null_context);
1281 null_context = NULL;
1285 enable leak reporting on exit
1287 void talloc_enable_leak_report(void)
1289 talloc_enable_null_tracking();
1290 atexit(talloc_report_null);
1294 enable full leak reporting on exit
1296 void talloc_enable_leak_report_full(void)
1298 talloc_enable_null_tracking();
1299 atexit(talloc_report_null_full);
1303 talloc and zero memory.
1305 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1307 void *p = _talloc_named_const(ctx, size, name);
1309 if (p) {
1310 memset(p, '\0', size);
1313 return p;
1317 memdup with a talloc.
1319 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1321 void *newp = _talloc_named_const(t, size, name);
1323 if (likely(newp)) {
1324 memcpy(newp, p, size);
1327 return newp;
1330 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1332 char *ret;
1334 ret = (char *)__talloc(t, len + 1);
1335 if (unlikely(!ret)) return NULL;
1337 memcpy(ret, p, len);
1338 ret[len] = 0;
1340 _talloc_set_name_const(ret, ret);
1341 return ret;
1345 strdup with a talloc
1347 char *talloc_strdup(const void *t, const char *p)
1349 if (unlikely(!p)) return NULL;
1350 return __talloc_strlendup(t, p, strlen(p));
1354 strndup with a talloc
1356 char *talloc_strndup(const void *t, const char *p, size_t n)
1358 if (unlikely(!p)) return NULL;
1359 return __talloc_strlendup(t, p, strnlen(p, n));
1362 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1363 const char *a, size_t alen)
1365 char *ret;
1367 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1368 if (unlikely(!ret)) return NULL;
1370 /* append the string and the trailing \0 */
1371 memcpy(&ret[slen], a, alen);
1372 ret[slen+alen] = 0;
1374 _talloc_set_name_const(ret, ret);
1375 return ret;
1379 * Appends at the end of the string.
1381 char *talloc_strdup_append(char *s, const char *a)
1383 if (unlikely(!s)) {
1384 return talloc_strdup(NULL, a);
1387 if (unlikely(!a)) {
1388 return s;
1391 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1395 * Appends at the end of the talloc'ed buffer,
1396 * not the end of the string.
1398 char *talloc_strdup_append_buffer(char *s, const char *a)
1400 size_t slen;
1402 if (unlikely(!s)) {
1403 return talloc_strdup(NULL, a);
1406 if (unlikely(!a)) {
1407 return s;
1410 slen = talloc_get_size(s);
1411 if (likely(slen > 0)) {
1412 slen--;
1415 return __talloc_strlendup_append(s, slen, a, strlen(a));
1419 * Appends at the end of the string.
1421 char *talloc_strndup_append(char *s, const char *a, size_t n)
1423 if (unlikely(!s)) {
1424 return talloc_strdup(NULL, a);
1427 if (unlikely(!a)) {
1428 return s;
1431 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1435 * Appends at the end of the talloc'ed buffer,
1436 * not the end of the string.
1438 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1440 size_t slen;
1442 if (unlikely(!s)) {
1443 return talloc_strdup(NULL, a);
1446 if (unlikely(!a)) {
1447 return s;
1450 slen = talloc_get_size(s);
1451 if (likely(slen > 0)) {
1452 slen--;
1455 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1458 #ifndef HAVE_VA_COPY
1459 #ifdef HAVE___VA_COPY
1460 #define va_copy(dest, src) __va_copy(dest, src)
1461 #else
1462 #define va_copy(dest, src) (dest) = (src)
1463 #endif
1464 #endif
1466 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1468 int len;
1469 char *ret;
1470 va_list ap2;
1471 char c;
1473 /* this call looks strange, but it makes it work on older solaris boxes */
1474 va_copy(ap2, ap);
1475 len = vsnprintf(&c, 1, fmt, ap2);
1476 va_end(ap2);
1477 if (unlikely(len < 0)) {
1478 abort(); // return NULL;
1481 ret = (char *)__talloc(t, len+1);
1482 if (unlikely(!ret)) return NULL;
1484 va_copy(ap2, ap);
1485 vsnprintf(ret, len+1, fmt, ap2);
1486 va_end(ap2);
1488 _talloc_set_name_const(ret, ret);
1489 return ret;
1494 Perform string formatting, and return a pointer to newly allocated
1495 memory holding the result, inside a memory pool.
1497 char *talloc_asprintf(const void *t, const char *fmt, ...)
1499 va_list ap;
1500 char *ret;
1502 va_start(ap, fmt);
1503 ret = talloc_vasprintf(t, fmt, ap);
1504 va_end(ap);
1505 return ret;
1508 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1509 const char *fmt, va_list ap)
1510 PRINTF_ATTRIBUTE(3,0);
1512 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1513 const char *fmt, va_list ap)
1515 ssize_t alen;
1516 va_list ap2;
1517 char c;
1519 va_copy(ap2, ap);
1520 alen = vsnprintf(&c, 1, fmt, ap2);
1521 va_end(ap2);
1523 if (alen <= 0) {
1524 /* Either the vsnprintf failed or the format resulted in
1525 * no characters being formatted. In the former case, we
1526 * ought to return NULL, in the latter we ought to return
1527 * the original string. Most current callers of this
1528 * function expect it to never return NULL.
1530 return s;
1533 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1534 if (!s) return NULL;
1536 va_copy(ap2, ap);
1537 vsnprintf(s + slen, alen + 1, fmt, ap2);
1538 va_end(ap2);
1540 _talloc_set_name_const(s, s);
1541 return s;
1545 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1546 * and return @p s, which may have moved. Good for gradually
1547 * accumulating output into a string buffer. Appends at the end
1548 * of the string.
1550 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1552 if (unlikely(!s)) {
1553 return talloc_vasprintf(NULL, fmt, ap);
1556 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1560 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1561 * and return @p s, which may have moved. Always appends at the
1562 * end of the talloc'ed buffer, not the end of the string.
1564 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1566 size_t slen;
1568 if (unlikely(!s)) {
1569 return talloc_vasprintf(NULL, fmt, ap);
1572 slen = talloc_get_size(s);
1573 if (likely(slen > 0)) {
1574 slen--;
1577 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1581 Realloc @p s to append the formatted result of @p fmt and return @p
1582 s, which may have moved. Good for gradually accumulating output
1583 into a string buffer.
1585 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1587 va_list ap;
1589 va_start(ap, fmt);
1590 s = talloc_vasprintf_append(s, fmt, ap);
1591 va_end(ap);
1592 return s;
1596 Realloc @p s to append the formatted result of @p fmt and return @p
1597 s, which may have moved. Good for gradually accumulating output
1598 into a buffer.
1600 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1602 va_list ap;
1604 va_start(ap, fmt);
1605 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1606 va_end(ap);
1607 return s;
1611 alloc an array, checking for integer overflow in the array size
1613 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1615 if (count >= MAX_TALLOC_SIZE/el_size) {
1616 abort(); // return NULL;
1618 return _talloc_named_const(ctx, el_size * count, name);
1622 alloc an zero array, checking for integer overflow in the array size
1624 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1626 if (count >= MAX_TALLOC_SIZE/el_size) {
1627 abort(); // return NULL;
1629 return _talloc_zero(ctx, el_size * count, name);
1633 realloc an array, checking for integer overflow in the array size
1635 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1637 if (count >= MAX_TALLOC_SIZE/el_size) {
1638 abort(); // return NULL;
1640 return _talloc_realloc(ctx, ptr, el_size * count, name);
1644 a function version of talloc_realloc(), so it can be passed as a function pointer
1645 to libraries that want a realloc function (a realloc function encapsulates
1646 all the basic capabilities of an allocation library, which is why this is useful)
1648 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1650 return _talloc_realloc(context, ptr, size, NULL);
1654 static int talloc_autofree_destructor(void *ptr)
1656 autofree_context = NULL;
1657 return 0;
1660 static void talloc_autofree(void)
1662 _talloc_free(autofree_context);
1666 return a context which will be auto-freed on exit
1667 this is useful for reducing the noise in leak reports
1669 void *talloc_autofree_context(void)
1671 if (autofree_context == NULL) {
1672 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1673 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1674 atexit(talloc_autofree);
1676 return autofree_context;
1679 size_t talloc_get_size(const void *context)
1681 struct talloc_chunk *tc;
1683 if (context == NULL)
1684 return 0;
1686 tc = talloc_chunk_from_ptr(context);
1688 return tc->size;
1692 find a parent of this context that has the given name, if any
1694 void *talloc_find_parent_byname(const void *context, const char *name)
1696 struct talloc_chunk *tc;
1698 if (context == NULL) {
1699 return NULL;
1702 tc = talloc_chunk_from_ptr(context);
1703 while (tc) {
1704 if (tc->name && strcmp(tc->name, name) == 0) {
1705 return TC_PTR_FROM_CHUNK(tc);
1707 while (tc && tc->prev) tc = tc->prev;
1708 if (tc) {
1709 tc = tc->parent;
1712 return NULL;
1716 show the parentage of a context
1718 void talloc_show_parents(const void *context, FILE *file)
1720 struct talloc_chunk *tc;
1722 if (context == NULL) {
1723 fprintf(file, "talloc no parents for NULL\n");
1724 return;
1727 tc = talloc_chunk_from_ptr(context);
1728 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1729 while (tc) {
1730 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1731 while (tc && tc->prev) tc = tc->prev;
1732 if (tc) {
1733 tc = tc->parent;
1736 fflush(file);
1740 return 1 if ptr is a parent of context
1742 int talloc_is_parent(const void *context, const void *ptr)
1744 struct talloc_chunk *tc;
1746 if (context == NULL) {
1747 return 0;
1750 tc = talloc_chunk_from_ptr(context);
1751 while (tc) {
1752 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1753 while (tc && tc->prev) tc = tc->prev;
1754 if (tc) {
1755 tc = tc->parent;
1758 return 0;