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
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/
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
48 /* use this to force every realloc to change the pointer, to stress test
49 code that might not cope */
50 #define ALWAYS_REALLOC 0
53 #define MAX_TALLOC_SIZE 0x10000000
54 #define TALLOC_MAGIC_BASE 0xe814ec70
55 #define TALLOC_MAGIC ( \
57 (TALLOC_VERSION_MAJOR << 12) + \
58 (TALLOC_VERSION_MINOR << 4) \
61 #define TALLOC_FLAG_FREE 0x01
62 #define TALLOC_FLAG_LOOP 0x02
63 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
64 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
65 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
67 /* by default we abort when given a bad pointer (such as when talloc_free() is called
68 on a pointer that came from malloc() */
70 #define TALLOC_ABORT(reason) abort()
73 #ifndef discard_const_p
74 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
75 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
77 # define discard_const_p(type, ptr) ((type *)(ptr))
81 /* these macros gain us a few percent of speed on gcc */
83 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
84 as its first argument */
86 #define likely(x) __builtin_expect(!!(x), 1)
89 #define unlikely(x) __builtin_expect(!!(x), 0)
96 #define unlikely(x) (x)
100 /* this null_context is only used if talloc_enable_leak_report() or
101 talloc_enable_leak_report_full() is called, otherwise it remains
104 static void *null_context
;
105 static void *autofree_context
;
107 /* used to enable fill of memory on free, which can be useful for
108 * catching use after free errors when valgrind is too slow
116 #define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
118 struct talloc_reference_handle
{
119 struct talloc_reference_handle
*next
, *prev
;
121 const char *location
;
124 typedef int (*talloc_destructor_t
)(void *);
126 struct talloc_chunk
{
127 struct talloc_chunk
*next
, *prev
;
128 struct talloc_chunk
*parent
, *child
;
129 struct talloc_reference_handle
*refs
;
130 talloc_destructor_t destructor
;
136 * "pool" has dual use:
138 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
139 * marks the end of the currently allocated area.
141 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
142 * is a pointer to the struct talloc_chunk of the pool that it was
143 * allocated from. This way children can quickly find the pool to chew
149 /* 16 byte alignment seems to keep everyone happy */
150 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
151 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
153 _PUBLIC_
int talloc_version_major(void)
155 return TALLOC_VERSION_MAJOR
;
158 _PUBLIC_
int talloc_version_minor(void)
160 return TALLOC_VERSION_MINOR
;
163 static void (*talloc_log_fn
)(const char *message
);
165 _PUBLIC_
void talloc_set_log_fn(void (*log_fn
)(const char *message
))
167 talloc_log_fn
= log_fn
;
170 static void talloc_log(const char *fmt
, ...) PRINTF_ATTRIBUTE(1,2);
171 static void talloc_log(const char *fmt
, ...)
176 if (!talloc_log_fn
) {
181 message
= talloc_vasprintf(NULL
, fmt
, ap
);
184 talloc_log_fn(message
);
185 talloc_free(message
);
188 static void talloc_log_stderr(const char *message
)
190 fprintf(stderr
, "%s", message
);
193 _PUBLIC_
void talloc_set_log_stderr(void)
195 talloc_set_log_fn(talloc_log_stderr
);
198 static void (*talloc_abort_fn
)(const char *reason
);
200 _PUBLIC_
void talloc_set_abort_fn(void (*abort_fn
)(const char *reason
))
202 talloc_abort_fn
= abort_fn
;
205 static void talloc_abort(const char *reason
)
207 talloc_log("%s\n", reason
);
209 if (!talloc_abort_fn
) {
210 TALLOC_ABORT(reason
);
213 talloc_abort_fn(reason
);
216 static void talloc_abort_magic(unsigned magic
)
218 unsigned striped
= magic
- TALLOC_MAGIC_BASE
;
219 unsigned major
= (striped
& 0xFFFFF000) >> 12;
220 unsigned minor
= (striped
& 0x00000FF0) >> 4;
221 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
223 TALLOC_MAGIC
, TALLOC_VERSION_MAJOR
, TALLOC_VERSION_MINOR
);
224 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
227 static void talloc_abort_double_free(void)
229 talloc_abort("Bad talloc magic value - double free");
232 static void talloc_abort_unknown_value(void)
234 talloc_abort("Bad talloc magic value - unknown value");
237 /* panic if we get a bad magic value */
238 static inline struct talloc_chunk
*talloc_chunk_from_ptr(const void *ptr
)
240 const char *pp
= (const char *)ptr
;
241 struct talloc_chunk
*tc
= discard_const_p(struct talloc_chunk
, pp
- TC_HDR_SIZE
);
242 if (unlikely((tc
->flags
& (TALLOC_FLAG_FREE
| ~0xF)) != TALLOC_MAGIC
)) {
243 if ((tc
->flags
& (~0xFFF)) == TALLOC_MAGIC_BASE
) {
244 talloc_abort_magic(tc
->flags
& (~0xF));
248 if (tc
->flags
& TALLOC_FLAG_FREE
) {
249 talloc_log("talloc: double free error - first free may be at %s\n", tc
->name
);
250 talloc_abort_double_free();
253 talloc_abort_unknown_value();
260 /* hook into the front of the list */
261 #define _TLIST_ADD(list, p) \
265 (p)->next = (p)->prev = NULL; \
267 (list)->prev = (p); \
268 (p)->next = (list); \
274 /* remove an element from a list - element doesn't have to be in list. */
275 #define _TLIST_REMOVE(list, p) \
277 if ((p) == (list)) { \
278 (list) = (p)->next; \
279 if (list) (list)->prev = NULL; \
281 if ((p)->prev) (p)->prev->next = (p)->next; \
282 if ((p)->next) (p)->next->prev = (p)->prev; \
284 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
289 return the parent chunk of a pointer
291 static inline struct talloc_chunk
*talloc_parent_chunk(const void *ptr
)
293 struct talloc_chunk
*tc
;
295 if (unlikely(ptr
== NULL
)) {
299 tc
= talloc_chunk_from_ptr(ptr
);
300 while (tc
->prev
) tc
=tc
->prev
;
305 _PUBLIC_
void *talloc_parent(const void *ptr
)
307 struct talloc_chunk
*tc
= talloc_parent_chunk(ptr
);
308 return tc
? TC_PTR_FROM_CHUNK(tc
) : NULL
;
314 _PUBLIC_
const char *talloc_parent_name(const void *ptr
)
316 struct talloc_chunk
*tc
= talloc_parent_chunk(ptr
);
317 return tc
? tc
->name
: NULL
;
321 A pool carries an in-pool object count count in the first 16 bytes.
322 bytes. This is done to support talloc_steal() to a parent outside of the
323 pool. The count includes the pool itself, so a talloc_free() on a pool will
324 only destroy the pool if the count has dropped to zero. A talloc_free() of a
325 pool member will reduce the count, and eventually also call free(3) on the
328 The object count is not put into "struct talloc_chunk" because it is only
329 relevant for talloc pools and the alignment to 16 bytes would increase the
330 memory footprint of each talloc chunk by those 16 bytes.
333 #define TALLOC_POOL_HDR_SIZE 16
335 static unsigned int *talloc_pool_objectcount(struct talloc_chunk
*tc
)
337 return (unsigned int *)((char *)tc
+ sizeof(struct talloc_chunk
));
344 static struct talloc_chunk
*talloc_alloc_pool(struct talloc_chunk
*parent
,
347 struct talloc_chunk
*pool_ctx
= NULL
;
349 struct talloc_chunk
*result
;
352 if (parent
== NULL
) {
356 if (parent
->flags
& TALLOC_FLAG_POOL
) {
359 else if (parent
->flags
& TALLOC_FLAG_POOLMEM
) {
360 pool_ctx
= (struct talloc_chunk
*)parent
->pool
;
363 if (pool_ctx
== NULL
) {
367 space_left
= ((char *)pool_ctx
+ TC_HDR_SIZE
+ pool_ctx
->size
)
368 - ((char *)pool_ctx
->pool
);
371 * Align size to 16 bytes
373 chunk_size
= ((size
+ 15) & ~15);
375 if (space_left
< chunk_size
) {
379 result
= (struct talloc_chunk
*)pool_ctx
->pool
;
381 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
382 VALGRIND_MAKE_MEM_UNDEFINED(result
, size
);
385 pool_ctx
->pool
= (void *)((char *)result
+ chunk_size
);
387 result
->flags
= TALLOC_MAGIC
| TALLOC_FLAG_POOLMEM
;
388 result
->pool
= pool_ctx
;
390 *talloc_pool_objectcount(pool_ctx
) += 1;
396 Allocate a bit of memory as a child of an existing pointer
398 static inline void *__talloc(const void *context
, size_t size
)
400 struct talloc_chunk
*tc
= NULL
;
402 if (unlikely(context
== NULL
)) {
403 context
= null_context
;
406 if (unlikely(size
>= MAX_TALLOC_SIZE
)) {
410 if (context
!= NULL
) {
411 tc
= talloc_alloc_pool(talloc_chunk_from_ptr(context
),
416 tc
= (struct talloc_chunk
*)malloc(TC_HDR_SIZE
+size
);
417 if (unlikely(tc
== NULL
)) return NULL
;
418 tc
->flags
= TALLOC_MAGIC
;
423 tc
->destructor
= NULL
;
428 if (likely(context
)) {
429 struct talloc_chunk
*parent
= talloc_chunk_from_ptr(context
);
432 parent
->child
->parent
= NULL
;
433 tc
->next
= parent
->child
;
442 tc
->next
= tc
->prev
= tc
->parent
= NULL
;
445 return TC_PTR_FROM_CHUNK(tc
);
449 * Create a talloc pool
452 _PUBLIC_
void *talloc_pool(const void *context
, size_t size
)
454 void *result
= __talloc(context
, size
+ TALLOC_POOL_HDR_SIZE
);
455 struct talloc_chunk
*tc
;
457 if (unlikely(result
== NULL
)) {
461 tc
= talloc_chunk_from_ptr(result
);
463 tc
->flags
|= TALLOC_FLAG_POOL
;
464 tc
->pool
= (char *)result
+ TALLOC_POOL_HDR_SIZE
;
466 *talloc_pool_objectcount(tc
) = 1;
468 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
469 VALGRIND_MAKE_MEM_NOACCESS(tc
->pool
, size
);
476 setup a destructor to be called on free of a pointer
477 the destructor should return 0 on success, or -1 on failure.
478 if the destructor fails then the free is failed, and the memory can
479 be continued to be used
481 _PUBLIC_
void _talloc_set_destructor(const void *ptr
, int (*destructor
)(void *))
483 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
484 tc
->destructor
= destructor
;
488 increase the reference count on a piece of memory.
490 _PUBLIC_
int talloc_increase_ref_count(const void *ptr
)
492 if (unlikely(!talloc_reference(null_context
, ptr
))) {
499 helper for talloc_reference()
501 this is referenced by a function pointer and should not be inline
503 static int talloc_reference_destructor(struct talloc_reference_handle
*handle
)
505 struct talloc_chunk
*ptr_tc
= talloc_chunk_from_ptr(handle
->ptr
);
506 _TLIST_REMOVE(ptr_tc
->refs
, handle
);
511 more efficient way to add a name to a pointer - the name must point to a
514 static inline void _talloc_set_name_const(const void *ptr
, const char *name
)
516 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
521 internal talloc_named_const()
523 static inline void *_talloc_named_const(const void *context
, size_t size
, const char *name
)
527 ptr
= __talloc(context
, size
);
528 if (unlikely(ptr
== NULL
)) {
532 _talloc_set_name_const(ptr
, name
);
538 make a secondary reference to a pointer, hanging off the given context.
539 the pointer remains valid until both the original caller and this given
542 the major use for this is when two different structures need to reference the
543 same underlying data, and you want to be able to free the two instances separately,
546 _PUBLIC_
void *_talloc_reference_loc(const void *context
, const void *ptr
, const char *location
)
548 struct talloc_chunk
*tc
;
549 struct talloc_reference_handle
*handle
;
550 if (unlikely(ptr
== NULL
)) return NULL
;
552 tc
= talloc_chunk_from_ptr(ptr
);
553 handle
= (struct talloc_reference_handle
*)_talloc_named_const(context
,
554 sizeof(struct talloc_reference_handle
),
555 TALLOC_MAGIC_REFERENCE
);
556 if (unlikely(handle
== NULL
)) return NULL
;
558 /* note that we hang the destructor off the handle, not the
559 main context as that allows the caller to still setup their
560 own destructor on the context if they want to */
561 talloc_set_destructor(handle
, talloc_reference_destructor
);
562 handle
->ptr
= discard_const_p(void, ptr
);
563 handle
->location
= location
;
564 _TLIST_ADD(tc
->refs
, handle
);
568 static void *_talloc_steal_internal(const void *new_ctx
, const void *ptr
);
571 internal talloc_free call
573 static inline int _talloc_free_internal(void *ptr
, const char *location
)
575 struct talloc_chunk
*tc
;
577 if (unlikely(ptr
== NULL
)) {
581 /* possibly initialised the talloc fill value */
582 if (!talloc_fill
.initialised
) {
583 const char *fill
= getenv(TALLOC_FILL_ENV
);
585 talloc_fill
.enabled
= true;
586 talloc_fill
.fill_value
= strtoul(fill
, NULL
, 0);
588 talloc_fill
.initialised
= true;
591 tc
= talloc_chunk_from_ptr(ptr
);
593 if (unlikely(tc
->refs
)) {
595 /* check if this is a reference from a child or
596 * grandchild back to it's parent or grandparent
598 * in that case we need to remove the reference and
599 * call another instance of talloc_free() on the current
602 is_child
= talloc_is_parent(tc
->refs
, ptr
);
603 _talloc_free_internal(tc
->refs
, location
);
605 return _talloc_free_internal(ptr
, location
);
610 if (unlikely(tc
->flags
& TALLOC_FLAG_LOOP
)) {
611 /* we have a free loop - stop looping */
615 if (unlikely(tc
->destructor
)) {
616 talloc_destructor_t d
= tc
->destructor
;
617 if (d
== (talloc_destructor_t
)-1) {
620 tc
->destructor
= (talloc_destructor_t
)-1;
625 tc
->destructor
= NULL
;
629 _TLIST_REMOVE(tc
->parent
->child
, tc
);
630 if (tc
->parent
->child
) {
631 tc
->parent
->child
->parent
= tc
->parent
;
634 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
635 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
638 tc
->flags
|= TALLOC_FLAG_LOOP
;
641 /* we need to work out who will own an abandoned child
642 if it cannot be freed. In priority order, the first
643 choice is owner of any remaining reference to this
644 pointer, the second choice is our parent, and the
645 final choice is the null context. */
646 void *child
= TC_PTR_FROM_CHUNK(tc
->child
);
647 const void *new_parent
= null_context
;
648 if (unlikely(tc
->child
->refs
)) {
649 struct talloc_chunk
*p
= talloc_parent_chunk(tc
->child
->refs
);
650 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
652 if (unlikely(_talloc_free_internal(child
, location
) == -1)) {
653 if (new_parent
== null_context
) {
654 struct talloc_chunk
*p
= talloc_parent_chunk(ptr
);
655 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
657 _talloc_steal_internal(new_parent
, child
);
661 tc
->flags
|= TALLOC_FLAG_FREE
;
663 /* we mark the freed memory with where we called the free
664 * from. This means on a double free error we can report where
665 * the first free came from
669 if (tc
->flags
& (TALLOC_FLAG_POOL
|TALLOC_FLAG_POOLMEM
)) {
670 struct talloc_chunk
*pool
;
671 unsigned int *pool_object_count
;
673 pool
= (tc
->flags
& TALLOC_FLAG_POOL
)
674 ? tc
: (struct talloc_chunk
*)tc
->pool
;
676 pool_object_count
= talloc_pool_objectcount(pool
);
678 if (*pool_object_count
== 0) {
679 talloc_abort("Pool object count zero!");
683 *pool_object_count
-= 1;
685 if (*pool_object_count
== 0) {
686 if (talloc_fill
.enabled
) {
687 memset(TC_PTR_FROM_CHUNK(pool
), talloc_fill
.fill_value
, pool
->size
);
693 if (talloc_fill
.enabled
) {
694 /* don't wipe the header, to allow the
695 double-free logic to still work
697 memset(TC_PTR_FROM_CHUNK(tc
), talloc_fill
.fill_value
, tc
->size
);
705 move a lump of memory from one talloc context to another return the
706 ptr on success, or NULL if it could not be transferred.
707 passing NULL as ptr will always return NULL with no side effects.
709 static void *_talloc_steal_internal(const void *new_ctx
, const void *ptr
)
711 struct talloc_chunk
*tc
, *new_tc
;
713 if (unlikely(!ptr
)) {
717 if (unlikely(new_ctx
== NULL
)) {
718 new_ctx
= null_context
;
721 tc
= talloc_chunk_from_ptr(ptr
);
723 if (unlikely(new_ctx
== NULL
)) {
725 _TLIST_REMOVE(tc
->parent
->child
, tc
);
726 if (tc
->parent
->child
) {
727 tc
->parent
->child
->parent
= tc
->parent
;
730 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
731 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
734 tc
->parent
= tc
->next
= tc
->prev
= NULL
;
735 return discard_const_p(void, ptr
);
738 new_tc
= talloc_chunk_from_ptr(new_ctx
);
740 if (unlikely(tc
== new_tc
|| tc
->parent
== new_tc
)) {
741 return discard_const_p(void, ptr
);
745 _TLIST_REMOVE(tc
->parent
->child
, tc
);
746 if (tc
->parent
->child
) {
747 tc
->parent
->child
->parent
= tc
->parent
;
750 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
751 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
755 if (new_tc
->child
) new_tc
->child
->parent
= NULL
;
756 _TLIST_ADD(new_tc
->child
, tc
);
758 return discard_const_p(void, ptr
);
762 move a lump of memory from one talloc context to another return the
763 ptr on success, or NULL if it could not be transferred.
764 passing NULL as ptr will always return NULL with no side effects.
766 _PUBLIC_
void *_talloc_steal_loc(const void *new_ctx
, const void *ptr
, const char *location
)
768 struct talloc_chunk
*tc
;
770 if (unlikely(ptr
== NULL
)) {
774 tc
= talloc_chunk_from_ptr(ptr
);
776 if (unlikely(tc
->refs
!= NULL
) && talloc_parent(ptr
) != new_ctx
) {
777 struct talloc_reference_handle
*h
;
779 talloc_log("WARNING: talloc_steal with references at %s\n",
782 for (h
=tc
->refs
; h
; h
=h
->next
) {
783 talloc_log("\treference at %s\n",
789 /* this test is probably too expensive to have on in the
790 normal build, but it useful for debugging */
791 if (talloc_is_parent(new_ctx
, ptr
)) {
792 talloc_log("WARNING: stealing into talloc child at %s\n", location
);
796 return _talloc_steal_internal(new_ctx
, ptr
);
800 this is like a talloc_steal(), but you must supply the old
801 parent. This resolves the ambiguity in a talloc_steal() which is
802 called on a context that has more than one parent (via references)
804 The old parent can be either a reference or a parent
806 _PUBLIC_
void *talloc_reparent(const void *old_parent
, const void *new_parent
, const void *ptr
)
808 struct talloc_chunk
*tc
;
809 struct talloc_reference_handle
*h
;
811 if (unlikely(ptr
== NULL
)) {
815 if (old_parent
== talloc_parent(ptr
)) {
816 return _talloc_steal_internal(new_parent
, ptr
);
819 tc
= talloc_chunk_from_ptr(ptr
);
820 for (h
=tc
->refs
;h
;h
=h
->next
) {
821 if (talloc_parent(h
) == old_parent
) {
822 if (_talloc_steal_internal(new_parent
, h
) != h
) {
825 return discard_const_p(void, ptr
);
829 /* it wasn't a parent */
834 remove a secondary reference to a pointer. This undo's what
835 talloc_reference() has done. The context and pointer arguments
836 must match those given to a talloc_reference()
838 static inline int talloc_unreference(const void *context
, const void *ptr
)
840 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
841 struct talloc_reference_handle
*h
;
843 if (unlikely(context
== NULL
)) {
844 context
= null_context
;
847 for (h
=tc
->refs
;h
;h
=h
->next
) {
848 struct talloc_chunk
*p
= talloc_parent_chunk(h
);
850 if (context
== NULL
) break;
851 } else if (TC_PTR_FROM_CHUNK(p
) == context
) {
859 return _talloc_free_internal(h
, __location__
);
863 remove a specific parent context from a pointer. This is a more
864 controlled varient of talloc_free()
866 _PUBLIC_
int talloc_unlink(const void *context
, void *ptr
)
868 struct talloc_chunk
*tc_p
, *new_p
;
875 if (context
== NULL
) {
876 context
= null_context
;
879 if (talloc_unreference(context
, ptr
) == 0) {
883 if (context
== NULL
) {
884 if (talloc_parent_chunk(ptr
) != NULL
) {
888 if (talloc_chunk_from_ptr(context
) != talloc_parent_chunk(ptr
)) {
893 tc_p
= talloc_chunk_from_ptr(ptr
);
895 if (tc_p
->refs
== NULL
) {
896 return _talloc_free_internal(ptr
, __location__
);
899 new_p
= talloc_parent_chunk(tc_p
->refs
);
901 new_parent
= TC_PTR_FROM_CHUNK(new_p
);
906 if (talloc_unreference(new_parent
, ptr
) != 0) {
910 _talloc_steal_internal(new_parent
, ptr
);
916 add a name to an existing pointer - va_list version
918 static inline const char *talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
920 static inline const char *talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
)
922 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
923 tc
->name
= talloc_vasprintf(ptr
, fmt
, ap
);
924 if (likely(tc
->name
)) {
925 _talloc_set_name_const(tc
->name
, ".name");
931 add a name to an existing pointer
933 _PUBLIC_
const char *talloc_set_name(const void *ptr
, const char *fmt
, ...)
938 name
= talloc_set_name_v(ptr
, fmt
, ap
);
945 create a named talloc pointer. Any talloc pointer can be named, and
946 talloc_named() operates just like talloc() except that it allows you
949 _PUBLIC_
void *talloc_named(const void *context
, size_t size
, const char *fmt
, ...)
955 ptr
= __talloc(context
, size
);
956 if (unlikely(ptr
== NULL
)) return NULL
;
959 name
= talloc_set_name_v(ptr
, fmt
, ap
);
962 if (unlikely(name
== NULL
)) {
963 _talloc_free_internal(ptr
, __location__
);
971 return the name of a talloc ptr, or "UNNAMED"
973 _PUBLIC_
const char *talloc_get_name(const void *ptr
)
975 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
976 if (unlikely(tc
->name
== TALLOC_MAGIC_REFERENCE
)) {
979 if (likely(tc
->name
)) {
987 check if a pointer has the given name. If it does, return the pointer,
988 otherwise return NULL
990 _PUBLIC_
void *talloc_check_name(const void *ptr
, const char *name
)
993 if (unlikely(ptr
== NULL
)) return NULL
;
994 pname
= talloc_get_name(ptr
);
995 if (likely(pname
== name
|| strcmp(pname
, name
) == 0)) {
996 return discard_const_p(void, ptr
);
1001 static void talloc_abort_type_missmatch(const char *location
,
1003 const char *expected
)
1007 reason
= talloc_asprintf(NULL
,
1008 "%s: Type mismatch: name[%s] expected[%s]",
1013 reason
= "Type mismatch";
1016 talloc_abort(reason
);
1019 _PUBLIC_
void *_talloc_get_type_abort(const void *ptr
, const char *name
, const char *location
)
1023 if (unlikely(ptr
== NULL
)) {
1024 talloc_abort_type_missmatch(location
, NULL
, name
);
1028 pname
= talloc_get_name(ptr
);
1029 if (likely(pname
== name
|| strcmp(pname
, name
) == 0)) {
1030 return discard_const_p(void, ptr
);
1033 talloc_abort_type_missmatch(location
, pname
, name
);
1038 this is for compatibility with older versions of talloc
1040 _PUBLIC_
void *talloc_init(const char *fmt
, ...)
1046 ptr
= __talloc(NULL
, 0);
1047 if (unlikely(ptr
== NULL
)) return NULL
;
1050 name
= talloc_set_name_v(ptr
, fmt
, ap
);
1053 if (unlikely(name
== NULL
)) {
1054 _talloc_free_internal(ptr
, __location__
);
1062 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1063 should probably not be used in new code. It's in here to keep the talloc
1064 code consistent across Samba 3 and 4.
1066 _PUBLIC_
void talloc_free_children(void *ptr
)
1068 struct talloc_chunk
*tc
;
1070 if (unlikely(ptr
== NULL
)) {
1074 tc
= talloc_chunk_from_ptr(ptr
);
1077 /* we need to work out who will own an abandoned child
1078 if it cannot be freed. In priority order, the first
1079 choice is owner of any remaining reference to this
1080 pointer, the second choice is our parent, and the
1081 final choice is the null context. */
1082 void *child
= TC_PTR_FROM_CHUNK(tc
->child
);
1083 const void *new_parent
= null_context
;
1084 if (unlikely(tc
->child
->refs
)) {
1085 struct talloc_chunk
*p
= talloc_parent_chunk(tc
->child
->refs
);
1086 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
1088 if (unlikely(talloc_free(child
) == -1)) {
1089 if (new_parent
== null_context
) {
1090 struct talloc_chunk
*p
= talloc_parent_chunk(ptr
);
1091 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
1093 _talloc_steal_internal(new_parent
, child
);
1097 if ((tc
->flags
& TALLOC_FLAG_POOL
)
1098 && (*talloc_pool_objectcount(tc
) == 1)) {
1099 tc
->pool
= ((char *)tc
+ TC_HDR_SIZE
+ TALLOC_POOL_HDR_SIZE
);
1100 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
1101 VALGRIND_MAKE_MEM_NOACCESS(
1102 tc
->pool
, tc
->size
- TALLOC_POOL_HDR_SIZE
);
1108 Allocate a bit of memory as a child of an existing pointer
1110 _PUBLIC_
void *_talloc(const void *context
, size_t size
)
1112 return __talloc(context
, size
);
1116 externally callable talloc_set_name_const()
1118 _PUBLIC_
void talloc_set_name_const(const void *ptr
, const char *name
)
1120 _talloc_set_name_const(ptr
, name
);
1124 create a named talloc pointer. Any talloc pointer can be named, and
1125 talloc_named() operates just like talloc() except that it allows you
1126 to name the pointer.
1128 _PUBLIC_
void *talloc_named_const(const void *context
, size_t size
, const char *name
)
1130 return _talloc_named_const(context
, size
, name
);
1134 free a talloc pointer. This also frees all child pointers of this
1137 return 0 if the memory is actually freed, otherwise -1. The memory
1138 will not be freed if the ref_count is > 1 or the destructor (if
1139 any) returns non-zero
1141 _PUBLIC_
int _talloc_free(void *ptr
, const char *location
)
1143 struct talloc_chunk
*tc
;
1145 if (unlikely(ptr
== NULL
)) {
1149 tc
= talloc_chunk_from_ptr(ptr
);
1151 if (unlikely(tc
->refs
!= NULL
)) {
1152 struct talloc_reference_handle
*h
;
1154 if (talloc_parent(ptr
) == null_context
&& tc
->refs
->next
== NULL
) {
1155 /* in this case we do know which parent should
1156 get this pointer, as there is really only
1158 return talloc_unlink(null_context
, ptr
);
1161 talloc_log("ERROR: talloc_free with references at %s\n",
1164 for (h
=tc
->refs
; h
; h
=h
->next
) {
1165 talloc_log("\treference at %s\n",
1171 return _talloc_free_internal(ptr
, location
);
1177 A talloc version of realloc. The context argument is only used if
1180 _PUBLIC_
void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
1182 struct talloc_chunk
*tc
;
1184 bool malloced
= false;
1186 /* size zero is equivalent to free() */
1187 if (unlikely(size
== 0)) {
1188 talloc_unlink(context
, ptr
);
1192 if (unlikely(size
>= MAX_TALLOC_SIZE
)) {
1196 /* realloc(NULL) is equivalent to malloc() */
1198 return _talloc_named_const(context
, size
, name
);
1201 tc
= talloc_chunk_from_ptr(ptr
);
1203 /* don't allow realloc on referenced pointers */
1204 if (unlikely(tc
->refs
)) {
1208 /* don't let anybody try to realloc a talloc_pool */
1209 if (unlikely(tc
->flags
& TALLOC_FLAG_POOL
)) {
1213 /* don't shrink if we have less than 1k to gain */
1214 if ((size
< tc
->size
) && ((tc
->size
- size
) < 1024)) {
1219 /* by resetting magic we catch users of the old memory */
1220 tc
->flags
|= TALLOC_FLAG_FREE
;
1223 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
1225 memcpy(new_ptr
, tc
, MIN(tc
->size
, size
) + TC_HDR_SIZE
);
1229 if (tc
->flags
& TALLOC_FLAG_POOLMEM
) {
1231 new_ptr
= talloc_alloc_pool(tc
, size
+ TC_HDR_SIZE
);
1232 *talloc_pool_objectcount((struct talloc_chunk
*)
1235 if (new_ptr
== NULL
) {
1236 new_ptr
= malloc(TC_HDR_SIZE
+size
);
1241 memcpy(new_ptr
, tc
, MIN(tc
->size
,size
) + TC_HDR_SIZE
);
1245 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
1248 if (unlikely(!new_ptr
)) {
1249 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1253 tc
= (struct talloc_chunk
*)new_ptr
;
1254 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1256 tc
->flags
&= ~TALLOC_FLAG_POOLMEM
;
1259 tc
->parent
->child
= tc
;
1262 tc
->child
->parent
= tc
;
1266 tc
->prev
->next
= tc
;
1269 tc
->next
->prev
= tc
;
1273 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc
), name
);
1275 return TC_PTR_FROM_CHUNK(tc
);
1279 a wrapper around talloc_steal() for situations where you are moving a pointer
1280 between two structures, and want the old pointer to be set to NULL
1282 _PUBLIC_
void *_talloc_move(const void *new_ctx
, const void *_pptr
)
1284 const void **pptr
= discard_const_p(const void *,_pptr
);
1285 void *ret
= talloc_steal(new_ctx
, discard_const_p(void, *pptr
));
1291 return the total size of a talloc pool (subtree)
1293 _PUBLIC_
size_t talloc_total_size(const void *ptr
)
1296 struct talloc_chunk
*c
, *tc
;
1305 tc
= talloc_chunk_from_ptr(ptr
);
1307 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1311 tc
->flags
|= TALLOC_FLAG_LOOP
;
1313 if (likely(tc
->name
!= TALLOC_MAGIC_REFERENCE
)) {
1316 for (c
=tc
->child
;c
;c
=c
->next
) {
1317 total
+= talloc_total_size(TC_PTR_FROM_CHUNK(c
));
1320 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
1326 return the total number of blocks in a talloc pool (subtree)
1328 _PUBLIC_
size_t talloc_total_blocks(const void *ptr
)
1331 struct talloc_chunk
*c
, *tc
;
1340 tc
= talloc_chunk_from_ptr(ptr
);
1342 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1346 tc
->flags
|= TALLOC_FLAG_LOOP
;
1349 for (c
=tc
->child
;c
;c
=c
->next
) {
1350 total
+= talloc_total_blocks(TC_PTR_FROM_CHUNK(c
));
1353 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
1359 return the number of external references to a pointer
1361 _PUBLIC_
size_t talloc_reference_count(const void *ptr
)
1363 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
1364 struct talloc_reference_handle
*h
;
1367 for (h
=tc
->refs
;h
;h
=h
->next
) {
1374 report on memory usage by all children of a pointer, giving a full tree view
1376 _PUBLIC_
void talloc_report_depth_cb(const void *ptr
, int depth
, int max_depth
,
1377 void (*callback
)(const void *ptr
,
1378 int depth
, int max_depth
,
1380 void *private_data
),
1383 struct talloc_chunk
*c
, *tc
;
1388 if (ptr
== NULL
) return;
1390 tc
= talloc_chunk_from_ptr(ptr
);
1392 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1396 callback(ptr
, depth
, max_depth
, 0, private_data
);
1398 if (max_depth
>= 0 && depth
>= max_depth
) {
1402 tc
->flags
|= TALLOC_FLAG_LOOP
;
1403 for (c
=tc
->child
;c
;c
=c
->next
) {
1404 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
1405 struct talloc_reference_handle
*h
= (struct talloc_reference_handle
*)TC_PTR_FROM_CHUNK(c
);
1406 callback(h
->ptr
, depth
+ 1, max_depth
, 1, private_data
);
1408 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c
), depth
+ 1, max_depth
, callback
, private_data
);
1411 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
1414 static void talloc_report_depth_FILE_helper(const void *ptr
, int depth
, int max_depth
, int is_ref
, void *_f
)
1416 const char *name
= talloc_get_name(ptr
);
1417 FILE *f
= (FILE *)_f
;
1420 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name
);
1425 fprintf(f
,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1426 (max_depth
< 0 ? "full " :""), name
,
1427 (unsigned long)talloc_total_size(ptr
),
1428 (unsigned long)talloc_total_blocks(ptr
));
1432 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1435 (unsigned long)talloc_total_size(ptr
),
1436 (unsigned long)talloc_total_blocks(ptr
),
1437 (int)talloc_reference_count(ptr
), ptr
);
1440 fprintf(f
, "content: ");
1441 if (talloc_total_size(ptr
)) {
1442 int tot
= talloc_total_size(ptr
);
1445 for (i
= 0; i
< tot
; i
++) {
1446 if ((((char *)ptr
)[i
] > 31) && (((char *)ptr
)[i
] < 126)) {
1447 fprintf(f
, "%c", ((char *)ptr
)[i
]);
1449 fprintf(f
, "~%02x", ((char *)ptr
)[i
]);
1458 report on memory usage by all children of a pointer, giving a full tree view
1460 _PUBLIC_
void talloc_report_depth_file(const void *ptr
, int depth
, int max_depth
, FILE *f
)
1463 talloc_report_depth_cb(ptr
, depth
, max_depth
, talloc_report_depth_FILE_helper
, f
);
1469 report on memory usage by all children of a pointer, giving a full tree view
1471 _PUBLIC_
void talloc_report_full(const void *ptr
, FILE *f
)
1473 talloc_report_depth_file(ptr
, 0, -1, f
);
1477 report on memory usage by all children of a pointer
1479 _PUBLIC_
void talloc_report(const void *ptr
, FILE *f
)
1481 talloc_report_depth_file(ptr
, 0, 1, f
);
1485 report on any memory hanging off the null context
1487 static void talloc_report_null(void)
1489 if (talloc_total_size(null_context
) != 0) {
1490 talloc_report(null_context
, stderr
);
1495 report on any memory hanging off the null context
1497 static void talloc_report_null_full(void)
1499 if (talloc_total_size(null_context
) != 0) {
1500 talloc_report_full(null_context
, stderr
);
1505 enable tracking of the NULL context
1507 _PUBLIC_
void talloc_enable_null_tracking(void)
1509 if (null_context
== NULL
) {
1510 null_context
= _talloc_named_const(NULL
, 0, "null_context");
1511 if (autofree_context
!= NULL
) {
1512 talloc_reparent(NULL
, null_context
, autofree_context
);
1518 enable tracking of the NULL context, not moving the autofree context
1519 into the NULL context. This is needed for the talloc testsuite
1521 _PUBLIC_
void talloc_enable_null_tracking_no_autofree(void)
1523 if (null_context
== NULL
) {
1524 null_context
= _talloc_named_const(NULL
, 0, "null_context");
1529 disable tracking of the NULL context
1531 _PUBLIC_
void talloc_disable_null_tracking(void)
1533 if (null_context
!= NULL
) {
1534 /* we have to move any children onto the real NULL
1536 struct talloc_chunk
*tc
, *tc2
;
1537 tc
= talloc_chunk_from_ptr(null_context
);
1538 for (tc2
= tc
->child
; tc2
; tc2
=tc2
->next
) {
1539 if (tc2
->parent
== tc
) tc2
->parent
= NULL
;
1540 if (tc2
->prev
== tc
) tc2
->prev
= NULL
;
1542 for (tc2
= tc
->next
; tc2
; tc2
=tc2
->next
) {
1543 if (tc2
->parent
== tc
) tc2
->parent
= NULL
;
1544 if (tc2
->prev
== tc
) tc2
->prev
= NULL
;
1549 talloc_free(null_context
);
1550 null_context
= NULL
;
1554 enable leak reporting on exit
1556 _PUBLIC_
void talloc_enable_leak_report(void)
1558 talloc_enable_null_tracking();
1559 atexit(talloc_report_null
);
1563 enable full leak reporting on exit
1565 _PUBLIC_
void talloc_enable_leak_report_full(void)
1567 talloc_enable_null_tracking();
1568 atexit(talloc_report_null_full
);
1572 talloc and zero memory.
1574 _PUBLIC_
void *_talloc_zero(const void *ctx
, size_t size
, const char *name
)
1576 void *p
= _talloc_named_const(ctx
, size
, name
);
1579 memset(p
, '\0', size
);
1586 memdup with a talloc.
1588 _PUBLIC_
void *_talloc_memdup(const void *t
, const void *p
, size_t size
, const char *name
)
1590 void *newp
= _talloc_named_const(t
, size
, name
);
1593 memcpy(newp
, p
, size
);
1599 static inline char *__talloc_strlendup(const void *t
, const char *p
, size_t len
)
1603 ret
= (char *)__talloc(t
, len
+ 1);
1604 if (unlikely(!ret
)) return NULL
;
1606 memcpy(ret
, p
, len
);
1609 _talloc_set_name_const(ret
, ret
);
1614 strdup with a talloc
1616 _PUBLIC_
char *talloc_strdup(const void *t
, const char *p
)
1618 if (unlikely(!p
)) return NULL
;
1619 return __talloc_strlendup(t
, p
, strlen(p
));
1623 strndup with a talloc
1625 _PUBLIC_
char *talloc_strndup(const void *t
, const char *p
, size_t n
)
1627 if (unlikely(!p
)) return NULL
;
1628 return __talloc_strlendup(t
, p
, strnlen(p
, n
));
1631 static inline char *__talloc_strlendup_append(char *s
, size_t slen
,
1632 const char *a
, size_t alen
)
1636 ret
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1637 if (unlikely(!ret
)) return NULL
;
1639 /* append the string and the trailing \0 */
1640 memcpy(&ret
[slen
], a
, alen
);
1643 _talloc_set_name_const(ret
, ret
);
1648 * Appends at the end of the string.
1650 _PUBLIC_
char *talloc_strdup_append(char *s
, const char *a
)
1653 return talloc_strdup(NULL
, a
);
1660 return __talloc_strlendup_append(s
, strlen(s
), a
, strlen(a
));
1664 * Appends at the end of the talloc'ed buffer,
1665 * not the end of the string.
1667 _PUBLIC_
char *talloc_strdup_append_buffer(char *s
, const char *a
)
1672 return talloc_strdup(NULL
, a
);
1679 slen
= talloc_get_size(s
);
1680 if (likely(slen
> 0)) {
1684 return __talloc_strlendup_append(s
, slen
, a
, strlen(a
));
1688 * Appends at the end of the string.
1690 _PUBLIC_
char *talloc_strndup_append(char *s
, const char *a
, size_t n
)
1693 return talloc_strdup(NULL
, a
);
1700 return __talloc_strlendup_append(s
, strlen(s
), a
, strnlen(a
, n
));
1704 * Appends at the end of the talloc'ed buffer,
1705 * not the end of the string.
1707 _PUBLIC_
char *talloc_strndup_append_buffer(char *s
, const char *a
, size_t n
)
1712 return talloc_strdup(NULL
, a
);
1719 slen
= talloc_get_size(s
);
1720 if (likely(slen
> 0)) {
1724 return __talloc_strlendup_append(s
, slen
, a
, strnlen(a
, n
));
1727 #ifndef HAVE_VA_COPY
1728 #ifdef HAVE___VA_COPY
1729 #define va_copy(dest, src) __va_copy(dest, src)
1731 #define va_copy(dest, src) (dest) = (src)
1735 _PUBLIC_
char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1742 /* this call looks strange, but it makes it work on older solaris boxes */
1744 len
= vsnprintf(&c
, 1, fmt
, ap2
);
1746 if (unlikely(len
< 0)) {
1750 ret
= (char *)__talloc(t
, len
+1);
1751 if (unlikely(!ret
)) return NULL
;
1754 vsnprintf(ret
, len
+1, fmt
, ap2
);
1757 _talloc_set_name_const(ret
, ret
);
1763 Perform string formatting, and return a pointer to newly allocated
1764 memory holding the result, inside a memory pool.
1766 _PUBLIC_
char *talloc_asprintf(const void *t
, const char *fmt
, ...)
1772 ret
= talloc_vasprintf(t
, fmt
, ap
);
1777 static inline char *__talloc_vaslenprintf_append(char *s
, size_t slen
,
1778 const char *fmt
, va_list ap
)
1779 PRINTF_ATTRIBUTE(3,0);
1781 static inline char *__talloc_vaslenprintf_append(char *s
, size_t slen
,
1782 const char *fmt
, va_list ap
)
1789 alen
= vsnprintf(&c
, 1, fmt
, ap2
);
1793 /* Either the vsnprintf failed or the format resulted in
1794 * no characters being formatted. In the former case, we
1795 * ought to return NULL, in the latter we ought to return
1796 * the original string. Most current callers of this
1797 * function expect it to never return NULL.
1802 s
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1803 if (!s
) return NULL
;
1806 vsnprintf(s
+ slen
, alen
+ 1, fmt
, ap2
);
1809 _talloc_set_name_const(s
, s
);
1814 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1815 * and return @p s, which may have moved. Good for gradually
1816 * accumulating output into a string buffer. Appends at the end
1819 _PUBLIC_
char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
1822 return talloc_vasprintf(NULL
, fmt
, ap
);
1825 return __talloc_vaslenprintf_append(s
, strlen(s
), fmt
, ap
);
1829 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1830 * and return @p s, which may have moved. Always appends at the
1831 * end of the talloc'ed buffer, not the end of the string.
1833 _PUBLIC_
char *talloc_vasprintf_append_buffer(char *s
, const char *fmt
, va_list ap
)
1838 return talloc_vasprintf(NULL
, fmt
, ap
);
1841 slen
= talloc_get_size(s
);
1842 if (likely(slen
> 0)) {
1846 return __talloc_vaslenprintf_append(s
, slen
, fmt
, ap
);
1850 Realloc @p s to append the formatted result of @p fmt and return @p
1851 s, which may have moved. Good for gradually accumulating output
1852 into a string buffer.
1854 _PUBLIC_
char *talloc_asprintf_append(char *s
, const char *fmt
, ...)
1859 s
= talloc_vasprintf_append(s
, fmt
, ap
);
1865 Realloc @p s to append the formatted result of @p fmt and return @p
1866 s, which may have moved. Good for gradually accumulating output
1869 _PUBLIC_
char *talloc_asprintf_append_buffer(char *s
, const char *fmt
, ...)
1874 s
= talloc_vasprintf_append_buffer(s
, fmt
, ap
);
1880 alloc an array, checking for integer overflow in the array size
1882 _PUBLIC_
void *_talloc_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1884 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1887 return _talloc_named_const(ctx
, el_size
* count
, name
);
1891 alloc an zero array, checking for integer overflow in the array size
1893 _PUBLIC_
void *_talloc_zero_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1895 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1898 return _talloc_zero(ctx
, el_size
* count
, name
);
1902 realloc an array, checking for integer overflow in the array size
1904 _PUBLIC_
void *_talloc_realloc_array(const void *ctx
, void *ptr
, size_t el_size
, unsigned count
, const char *name
)
1906 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1909 return _talloc_realloc(ctx
, ptr
, el_size
* count
, name
);
1913 a function version of talloc_realloc(), so it can be passed as a function pointer
1914 to libraries that want a realloc function (a realloc function encapsulates
1915 all the basic capabilities of an allocation library, which is why this is useful)
1917 _PUBLIC_
void *talloc_realloc_fn(const void *context
, void *ptr
, size_t size
)
1919 return _talloc_realloc(context
, ptr
, size
, NULL
);
1923 static int talloc_autofree_destructor(void *ptr
)
1925 autofree_context
= NULL
;
1929 static void talloc_autofree(void)
1931 talloc_free(autofree_context
);
1935 return a context which will be auto-freed on exit
1936 this is useful for reducing the noise in leak reports
1938 _PUBLIC_
void *talloc_autofree_context(void)
1940 if (autofree_context
== NULL
) {
1941 autofree_context
= _talloc_named_const(NULL
, 0, "autofree_context");
1942 talloc_set_destructor(autofree_context
, talloc_autofree_destructor
);
1943 atexit(talloc_autofree
);
1945 return autofree_context
;
1948 _PUBLIC_
size_t talloc_get_size(const void *context
)
1950 struct talloc_chunk
*tc
;
1952 if (context
== NULL
) {
1953 context
= null_context
;
1955 if (context
== NULL
) {
1959 tc
= talloc_chunk_from_ptr(context
);
1965 find a parent of this context that has the given name, if any
1967 _PUBLIC_
void *talloc_find_parent_byname(const void *context
, const char *name
)
1969 struct talloc_chunk
*tc
;
1971 if (context
== NULL
) {
1975 tc
= talloc_chunk_from_ptr(context
);
1977 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1978 return TC_PTR_FROM_CHUNK(tc
);
1980 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1989 show the parentage of a context
1991 _PUBLIC_
void talloc_show_parents(const void *context
, FILE *file
)
1993 struct talloc_chunk
*tc
;
1995 if (context
== NULL
) {
1996 fprintf(file
, "talloc no parents for NULL\n");
2000 tc
= talloc_chunk_from_ptr(context
);
2001 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
2003 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
2004 while (tc
&& tc
->prev
) tc
= tc
->prev
;
2013 return 1 if ptr is a parent of context
2015 static int _talloc_is_parent(const void *context
, const void *ptr
, int depth
)
2017 struct talloc_chunk
*tc
;
2019 if (context
== NULL
) {
2023 tc
= talloc_chunk_from_ptr(context
);
2024 while (tc
&& depth
> 0) {
2025 if (TC_PTR_FROM_CHUNK(tc
) == ptr
) return 1;
2026 while (tc
&& tc
->prev
) tc
= tc
->prev
;
2036 return 1 if ptr is a parent of context
2038 _PUBLIC_
int talloc_is_parent(const void *context
, const void *ptr
)
2040 return _talloc_is_parent(context
, ptr
, TALLOC_MAX_DEPTH
);