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_ALIGN16(s) (((s)+15)&~15)
151 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
152 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
154 _PUBLIC_ int talloc_version_major(void)
156 return TALLOC_VERSION_MAJOR;
159 _PUBLIC_ int talloc_version_minor(void)
161 return TALLOC_VERSION_MINOR;
164 static void (*talloc_log_fn)(const char *message);
166 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
168 talloc_log_fn = log_fn;
171 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
172 static void talloc_log(const char *fmt, ...)
177 if (!talloc_log_fn) {
182 message = talloc_vasprintf(NULL, fmt, ap);
185 talloc_log_fn(message);
186 talloc_free(message);
189 static void talloc_log_stderr(const char *message)
191 fprintf(stderr, "%s", message);
194 _PUBLIC_ void talloc_set_log_stderr(void)
196 talloc_set_log_fn(talloc_log_stderr);
199 static void (*talloc_abort_fn)(const char *reason);
201 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
203 talloc_abort_fn = abort_fn;
206 static void talloc_abort(const char *reason)
208 talloc_log("%s\n", reason);
210 if (!talloc_abort_fn) {
211 TALLOC_ABORT(reason);
214 talloc_abort_fn(reason);
217 static void talloc_abort_magic(unsigned magic)
219 unsigned striped = magic - TALLOC_MAGIC_BASE;
220 unsigned major = (striped & 0xFFFFF000) >> 12;
221 unsigned minor = (striped & 0x00000FF0) >> 4;
222 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
224 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
225 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
228 static void talloc_abort_access_after_free(void)
230 talloc_abort("Bad talloc magic value - access after free");
233 static void talloc_abort_unknown_value(void)
235 talloc_abort("Bad talloc magic value - unknown value");
238 /* panic if we get a bad magic value */
239 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
241 const char *pp = (const char *)ptr;
242 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
243 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
244 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
245 talloc_abort_magic(tc->flags & (~0xF));
249 if (tc->flags & TALLOC_FLAG_FREE) {
250 talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
251 talloc_abort_access_after_free();
254 talloc_abort_unknown_value();
261 /* hook into the front of the list */
262 #define _TLIST_ADD(list, p) \
266 (p)->next = (p)->prev = NULL; \
268 (list)->prev = (p); \
269 (p)->next = (list); \
275 /* remove an element from a list - element doesn't have to be in list. */
276 #define _TLIST_REMOVE(list, p) \
278 if ((p) == (list)) { \
279 (list) = (p)->next; \
280 if (list) (list)->prev = NULL; \
282 if ((p)->prev) (p)->prev->next = (p)->next; \
283 if ((p)->next) (p)->next->prev = (p)->prev; \
285 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
290 return the parent chunk of a pointer
292 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
294 struct talloc_chunk *tc;
296 if (unlikely(ptr == NULL)) {
300 tc = talloc_chunk_from_ptr(ptr);
301 while (tc->prev) tc=tc->prev;
306 _PUBLIC_ void *talloc_parent(const void *ptr)
308 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
309 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
315 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
317 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
318 return tc? tc->name : NULL;
322 A pool carries an in-pool object count count in the first 16 bytes.
323 bytes. This is done to support talloc_steal() to a parent outside of the
324 pool. The count includes the pool itself, so a talloc_free() on a pool will
325 only destroy the pool if the count has dropped to zero. A talloc_free() of a
326 pool member will reduce the count, and eventually also call free(3) on the
329 The object count is not put into "struct talloc_chunk" because it is only
330 relevant for talloc pools and the alignment to 16 bytes would increase the
331 memory footprint of each talloc chunk by those 16 bytes.
334 #define TALLOC_POOL_HDR_SIZE 16
336 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
338 return (unsigned int *)((char *)tc + TC_HDR_SIZE);
345 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
348 struct talloc_chunk *pool_ctx = NULL;
350 struct talloc_chunk *result;
353 if (parent == NULL) {
357 if (parent->flags & TALLOC_FLAG_POOL) {
360 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
361 pool_ctx = (struct talloc_chunk *)parent->pool;
364 if (pool_ctx == NULL) {
368 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
369 - ((char *)pool_ctx->pool);
372 * Align size to 16 bytes
374 chunk_size = TC_ALIGN16(size);
376 if (space_left < chunk_size) {
380 result = (struct talloc_chunk *)pool_ctx->pool;
382 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
383 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
386 pool_ctx->pool = (void *)((char *)result + chunk_size);
388 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
389 result->pool = pool_ctx;
391 *talloc_pool_objectcount(pool_ctx) += 1;
397 Allocate a bit of memory as a child of an existing pointer
399 static inline void *__talloc(const void *context, size_t size)
401 struct talloc_chunk *tc = NULL;
403 if (unlikely(context == NULL)) {
404 context = null_context;
407 if (unlikely(size >= MAX_TALLOC_SIZE)) {
411 if (context != NULL) {
412 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
417 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
418 if (unlikely(tc == NULL)) return NULL;
419 tc->flags = TALLOC_MAGIC;
424 tc->destructor = NULL;
429 if (likely(context)) {
430 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
433 parent->child->parent = NULL;
434 tc->next = parent->child;
443 tc->next = tc->prev = tc->parent = NULL;
446 return TC_PTR_FROM_CHUNK(tc);
450 * Create a talloc pool
453 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
455 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
456 struct talloc_chunk *tc;
458 if (unlikely(result == NULL)) {
462 tc = talloc_chunk_from_ptr(result);
464 tc->flags |= TALLOC_FLAG_POOL;
465 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
467 *talloc_pool_objectcount(tc) = 1;
469 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
470 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
477 setup a destructor to be called on free of a pointer
478 the destructor should return 0 on success, or -1 on failure.
479 if the destructor fails then the free is failed, and the memory can
480 be continued to be used
482 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
484 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
485 tc->destructor = destructor;
489 increase the reference count on a piece of memory.
491 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
493 if (unlikely(!talloc_reference(null_context, ptr))) {
500 helper for talloc_reference()
502 this is referenced by a function pointer and should not be inline
504 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
506 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
507 _TLIST_REMOVE(ptr_tc->refs, handle);
512 more efficient way to add a name to a pointer - the name must point to a
515 static inline void _talloc_set_name_const(const void *ptr, const char *name)
517 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
522 internal talloc_named_const()
524 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
528 ptr = __talloc(context, size);
529 if (unlikely(ptr == NULL)) {
533 _talloc_set_name_const(ptr, name);
539 make a secondary reference to a pointer, hanging off the given context.
540 the pointer remains valid until both the original caller and this given
543 the major use for this is when two different structures need to reference the
544 same underlying data, and you want to be able to free the two instances separately,
547 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
549 struct talloc_chunk *tc;
550 struct talloc_reference_handle *handle;
551 if (unlikely(ptr == NULL)) return NULL;
553 tc = talloc_chunk_from_ptr(ptr);
554 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
555 sizeof(struct talloc_reference_handle),
556 TALLOC_MAGIC_REFERENCE);
557 if (unlikely(handle == NULL)) return NULL;
559 /* note that we hang the destructor off the handle, not the
560 main context as that allows the caller to still setup their
561 own destructor on the context if they want to */
562 talloc_set_destructor(handle, talloc_reference_destructor);
563 handle->ptr = discard_const_p(void, ptr);
564 handle->location = location;
565 _TLIST_ADD(tc->refs, handle);
569 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
572 internal talloc_free call
574 static inline int _talloc_free_internal(void *ptr, const char *location)
576 struct talloc_chunk *tc;
578 if (unlikely(ptr == NULL)) {
582 /* possibly initialised the talloc fill value */
583 if (!talloc_fill.initialised) {
584 const char *fill = getenv(TALLOC_FILL_ENV);
586 talloc_fill.enabled = true;
587 talloc_fill.fill_value = strtoul(fill, NULL, 0);
589 talloc_fill.initialised = true;
592 tc = talloc_chunk_from_ptr(ptr);
594 if (unlikely(tc->refs)) {
596 /* check if this is a reference from a child or
597 * grandchild back to it's parent or grandparent
599 * in that case we need to remove the reference and
600 * call another instance of talloc_free() on the current
603 is_child = talloc_is_parent(tc->refs, ptr);
604 _talloc_free_internal(tc->refs, location);
606 return _talloc_free_internal(ptr, location);
611 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
612 /* we have a free loop - stop looping */
616 if (unlikely(tc->destructor)) {
617 talloc_destructor_t d = tc->destructor;
618 if (d == (talloc_destructor_t)-1) {
621 tc->destructor = (talloc_destructor_t)-1;
626 tc->destructor = NULL;
630 _TLIST_REMOVE(tc->parent->child, tc);
631 if (tc->parent->child) {
632 tc->parent->child->parent = tc->parent;
635 if (tc->prev) tc->prev->next = tc->next;
636 if (tc->next) tc->next->prev = tc->prev;
639 tc->flags |= TALLOC_FLAG_LOOP;
642 /* we need to work out who will own an abandoned child
643 if it cannot be freed. In priority order, the first
644 choice is owner of any remaining reference to this
645 pointer, the second choice is our parent, and the
646 final choice is the null context. */
647 void *child = TC_PTR_FROM_CHUNK(tc->child);
648 const void *new_parent = null_context;
649 struct talloc_chunk *old_parent = NULL;
650 if (unlikely(tc->child->refs)) {
651 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
652 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
654 /* finding the parent here is potentially quite
655 expensive, but the alternative, which is to change
656 talloc to always have a valid tc->parent pointer,
657 makes realloc more expensive where there are a
658 large number of children.
660 The reason we need the parent pointer here is that
661 if _talloc_free_internal() fails due to references
662 or a failing destructor we need to re-parent, but
663 the free call can invalidate the prev pointer.
665 if (new_parent == null_context && (tc->child->refs || tc->child->destructor)) {
666 old_parent = talloc_parent_chunk(ptr);
668 if (unlikely(_talloc_free_internal(child, location) == -1)) {
669 if (new_parent == null_context) {
670 struct talloc_chunk *p = old_parent;
671 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
673 _talloc_steal_internal(new_parent, child);
677 tc->flags |= TALLOC_FLAG_FREE;
679 /* we mark the freed memory with where we called the free
680 * from. This means on a double free error we can report where
681 * the first free came from
685 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
686 struct talloc_chunk *pool;
687 unsigned int *pool_object_count;
689 pool = (tc->flags & TALLOC_FLAG_POOL)
690 ? tc : (struct talloc_chunk *)tc->pool;
692 pool_object_count = talloc_pool_objectcount(pool);
694 if (*pool_object_count == 0) {
695 talloc_abort("Pool object count zero!");
699 *pool_object_count -= 1;
701 if (*pool_object_count == 0) {
702 if (talloc_fill.enabled) {
703 memset(TC_PTR_FROM_CHUNK(pool), talloc_fill.fill_value, pool->size);
709 if (talloc_fill.enabled) {
710 /* don't wipe the header, to allow the
711 double-free logic to still work
713 memset(TC_PTR_FROM_CHUNK(tc), talloc_fill.fill_value, tc->size);
721 move a lump of memory from one talloc context to another return the
722 ptr on success, or NULL if it could not be transferred.
723 passing NULL as ptr will always return NULL with no side effects.
725 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
727 struct talloc_chunk *tc, *new_tc;
729 if (unlikely(!ptr)) {
733 if (unlikely(new_ctx == NULL)) {
734 new_ctx = null_context;
737 tc = talloc_chunk_from_ptr(ptr);
739 if (unlikely(new_ctx == NULL)) {
741 _TLIST_REMOVE(tc->parent->child, tc);
742 if (tc->parent->child) {
743 tc->parent->child->parent = tc->parent;
746 if (tc->prev) tc->prev->next = tc->next;
747 if (tc->next) tc->next->prev = tc->prev;
750 tc->parent = tc->next = tc->prev = NULL;
751 return discard_const_p(void, ptr);
754 new_tc = talloc_chunk_from_ptr(new_ctx);
756 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
757 return discard_const_p(void, ptr);
761 _TLIST_REMOVE(tc->parent->child, tc);
762 if (tc->parent->child) {
763 tc->parent->child->parent = tc->parent;
766 if (tc->prev) tc->prev->next = tc->next;
767 if (tc->next) tc->next->prev = tc->prev;
771 if (new_tc->child) new_tc->child->parent = NULL;
772 _TLIST_ADD(new_tc->child, tc);
774 return discard_const_p(void, ptr);
778 move a lump of memory from one talloc context to another return the
779 ptr on success, or NULL if it could not be transferred.
780 passing NULL as ptr will always return NULL with no side effects.
782 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
784 struct talloc_chunk *tc;
786 if (unlikely(ptr == NULL)) {
790 tc = talloc_chunk_from_ptr(ptr);
792 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
793 struct talloc_reference_handle *h;
795 talloc_log("WARNING: talloc_steal with references at %s\n",
798 for (h=tc->refs; h; h=h->next) {
799 talloc_log("\treference at %s\n",
805 /* this test is probably too expensive to have on in the
806 normal build, but it useful for debugging */
807 if (talloc_is_parent(new_ctx, ptr)) {
808 talloc_log("WARNING: stealing into talloc child at %s\n", location);
812 return _talloc_steal_internal(new_ctx, ptr);
816 this is like a talloc_steal(), but you must supply the old
817 parent. This resolves the ambiguity in a talloc_steal() which is
818 called on a context that has more than one parent (via references)
820 The old parent can be either a reference or a parent
822 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
824 struct talloc_chunk *tc;
825 struct talloc_reference_handle *h;
827 if (unlikely(ptr == NULL)) {
831 if (old_parent == talloc_parent(ptr)) {
832 return _talloc_steal_internal(new_parent, ptr);
835 tc = talloc_chunk_from_ptr(ptr);
836 for (h=tc->refs;h;h=h->next) {
837 if (talloc_parent(h) == old_parent) {
838 if (_talloc_steal_internal(new_parent, h) != h) {
841 return discard_const_p(void, ptr);
845 /* it wasn't a parent */
850 remove a secondary reference to a pointer. This undo's what
851 talloc_reference() has done. The context and pointer arguments
852 must match those given to a talloc_reference()
854 static inline int talloc_unreference(const void *context, const void *ptr)
856 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
857 struct talloc_reference_handle *h;
859 if (unlikely(context == NULL)) {
860 context = null_context;
863 for (h=tc->refs;h;h=h->next) {
864 struct talloc_chunk *p = talloc_parent_chunk(h);
866 if (context == NULL) break;
867 } else if (TC_PTR_FROM_CHUNK(p) == context) {
875 return _talloc_free_internal(h, __location__);
879 remove a specific parent context from a pointer. This is a more
880 controlled varient of talloc_free()
882 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
884 struct talloc_chunk *tc_p, *new_p;
891 if (context == NULL) {
892 context = null_context;
895 if (talloc_unreference(context, ptr) == 0) {
899 if (context == NULL) {
900 if (talloc_parent_chunk(ptr) != NULL) {
904 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
909 tc_p = talloc_chunk_from_ptr(ptr);
911 if (tc_p->refs == NULL) {
912 return _talloc_free_internal(ptr, __location__);
915 new_p = talloc_parent_chunk(tc_p->refs);
917 new_parent = TC_PTR_FROM_CHUNK(new_p);
922 if (talloc_unreference(new_parent, ptr) != 0) {
926 _talloc_steal_internal(new_parent, ptr);
932 add a name to an existing pointer - va_list version
934 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
936 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
938 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
939 tc->name = talloc_vasprintf(ptr, fmt, ap);
940 if (likely(tc->name)) {
941 _talloc_set_name_const(tc->name, ".name");
947 add a name to an existing pointer
949 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
954 name = talloc_set_name_v(ptr, fmt, ap);
961 create a named talloc pointer. Any talloc pointer can be named, and
962 talloc_named() operates just like talloc() except that it allows you
965 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
971 ptr = __talloc(context, size);
972 if (unlikely(ptr == NULL)) return NULL;
975 name = talloc_set_name_v(ptr, fmt, ap);
978 if (unlikely(name == NULL)) {
979 _talloc_free_internal(ptr, __location__);
987 return the name of a talloc ptr, or "UNNAMED"
989 _PUBLIC_ const char *talloc_get_name(const void *ptr)
991 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
992 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
995 if (likely(tc->name)) {
1003 check if a pointer has the given name. If it does, return the pointer,
1004 otherwise return NULL
1006 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1009 if (unlikely(ptr == NULL)) return NULL;
1010 pname = talloc_get_name(ptr);
1011 if (likely(pname == name || strcmp(pname, name) == 0)) {
1012 return discard_const_p(void, ptr);
1017 static void talloc_abort_type_missmatch(const char *location,
1019 const char *expected)
1023 reason = talloc_asprintf(NULL,
1024 "%s: Type mismatch: name[%s] expected[%s]",
1029 reason = "Type mismatch";
1032 talloc_abort(reason);
1035 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1039 if (unlikely(ptr == NULL)) {
1040 talloc_abort_type_missmatch(location, NULL, name);
1044 pname = talloc_get_name(ptr);
1045 if (likely(pname == name || strcmp(pname, name) == 0)) {
1046 return discard_const_p(void, ptr);
1049 talloc_abort_type_missmatch(location, pname, name);
1054 this is for compatibility with older versions of talloc
1056 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1062 ptr = __talloc(NULL, 0);
1063 if (unlikely(ptr == NULL)) return NULL;
1066 name = talloc_set_name_v(ptr, fmt, ap);
1069 if (unlikely(name == NULL)) {
1070 _talloc_free_internal(ptr, __location__);
1078 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1079 should probably not be used in new code. It's in here to keep the talloc
1080 code consistent across Samba 3 and 4.
1082 _PUBLIC_ void talloc_free_children(void *ptr)
1084 struct talloc_chunk *tc;
1086 if (unlikely(ptr == NULL)) {
1090 tc = talloc_chunk_from_ptr(ptr);
1093 /* we need to work out who will own an abandoned child
1094 if it cannot be freed. In priority order, the first
1095 choice is owner of any remaining reference to this
1096 pointer, the second choice is our parent, and the
1097 final choice is the null context. */
1098 void *child = TC_PTR_FROM_CHUNK(tc->child);
1099 const void *new_parent = null_context;
1100 if (unlikely(tc->child->refs)) {
1101 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1102 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1104 if (unlikely(talloc_free(child) == -1)) {
1105 if (new_parent == null_context) {
1106 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1107 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1109 _talloc_steal_internal(new_parent, child);
1113 if ((tc->flags & TALLOC_FLAG_POOL)
1114 && (*talloc_pool_objectcount(tc) == 1)) {
1115 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
1116 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
1117 VALGRIND_MAKE_MEM_NOACCESS(
1118 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
1124 Allocate a bit of memory as a child of an existing pointer
1126 _PUBLIC_ void *_talloc(const void *context, size_t size)
1128 return __talloc(context, size);
1132 externally callable talloc_set_name_const()
1134 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1136 _talloc_set_name_const(ptr, name);
1140 create a named talloc pointer. Any talloc pointer can be named, and
1141 talloc_named() operates just like talloc() except that it allows you
1142 to name the pointer.
1144 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1146 return _talloc_named_const(context, size, name);
1150 free a talloc pointer. This also frees all child pointers of this
1153 return 0 if the memory is actually freed, otherwise -1. The memory
1154 will not be freed if the ref_count is > 1 or the destructor (if
1155 any) returns non-zero
1157 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1159 struct talloc_chunk *tc;
1161 if (unlikely(ptr == NULL)) {
1165 tc = talloc_chunk_from_ptr(ptr);
1167 if (unlikely(tc->refs != NULL)) {
1168 struct talloc_reference_handle *h;
1170 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1171 /* in this case we do know which parent should
1172 get this pointer, as there is really only
1174 return talloc_unlink(null_context, ptr);
1177 talloc_log("ERROR: talloc_free with references at %s\n",
1180 for (h=tc->refs; h; h=h->next) {
1181 talloc_log("\treference at %s\n",
1187 return _talloc_free_internal(ptr, location);
1193 A talloc version of realloc. The context argument is only used if
1196 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1198 struct talloc_chunk *tc;
1200 bool malloced = false;
1202 /* size zero is equivalent to free() */
1203 if (unlikely(size == 0)) {
1204 talloc_unlink(context, ptr);
1208 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1212 /* realloc(NULL) is equivalent to malloc() */
1214 return _talloc_named_const(context, size, name);
1217 tc = talloc_chunk_from_ptr(ptr);
1219 /* don't allow realloc on referenced pointers */
1220 if (unlikely(tc->refs)) {
1224 /* don't let anybody try to realloc a talloc_pool */
1225 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1229 /* don't shrink if we have less than 1k to gain */
1230 if ((size < tc->size) && ((tc->size - size) < 1024)) {
1235 /* by resetting magic we catch users of the old memory */
1236 tc->flags |= TALLOC_FLAG_FREE;
1239 new_ptr = malloc(size + TC_HDR_SIZE);
1241 memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1245 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1247 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1248 *talloc_pool_objectcount((struct talloc_chunk *)
1251 if (new_ptr == NULL) {
1252 new_ptr = malloc(TC_HDR_SIZE+size);
1257 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1261 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1264 if (unlikely(!new_ptr)) {
1265 tc->flags &= ~TALLOC_FLAG_FREE;
1269 tc = (struct talloc_chunk *)new_ptr;
1270 tc->flags &= ~TALLOC_FLAG_FREE;
1272 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1275 tc->parent->child = tc;
1278 tc->child->parent = tc;
1282 tc->prev->next = tc;
1285 tc->next->prev = tc;
1289 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1291 return TC_PTR_FROM_CHUNK(tc);
1295 a wrapper around talloc_steal() for situations where you are moving a pointer
1296 between two structures, and want the old pointer to be set to NULL
1298 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1300 const void **pptr = discard_const_p(const void *,_pptr);
1301 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1307 return the total size of a talloc pool (subtree)
1309 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1312 struct talloc_chunk *c, *tc;
1321 tc = talloc_chunk_from_ptr(ptr);
1323 if (tc->flags & TALLOC_FLAG_LOOP) {
1327 tc->flags |= TALLOC_FLAG_LOOP;
1329 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1332 for (c=tc->child;c;c=c->next) {
1333 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1336 tc->flags &= ~TALLOC_FLAG_LOOP;
1342 return the total number of blocks in a talloc pool (subtree)
1344 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1347 struct talloc_chunk *c, *tc;
1356 tc = talloc_chunk_from_ptr(ptr);
1358 if (tc->flags & TALLOC_FLAG_LOOP) {
1362 tc->flags |= TALLOC_FLAG_LOOP;
1365 for (c=tc->child;c;c=c->next) {
1366 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1369 tc->flags &= ~TALLOC_FLAG_LOOP;
1375 return the number of external references to a pointer
1377 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1379 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1380 struct talloc_reference_handle *h;
1383 for (h=tc->refs;h;h=h->next) {
1390 report on memory usage by all children of a pointer, giving a full tree view
1392 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1393 void (*callback)(const void *ptr,
1394 int depth, int max_depth,
1396 void *private_data),
1399 struct talloc_chunk *c, *tc;
1404 if (ptr == NULL) return;
1406 tc = talloc_chunk_from_ptr(ptr);
1408 if (tc->flags & TALLOC_FLAG_LOOP) {
1412 callback(ptr, depth, max_depth, 0, private_data);
1414 if (max_depth >= 0 && depth >= max_depth) {
1418 tc->flags |= TALLOC_FLAG_LOOP;
1419 for (c=tc->child;c;c=c->next) {
1420 if (c->name == TALLOC_MAGIC_REFERENCE) {
1421 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1422 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1424 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1427 tc->flags &= ~TALLOC_FLAG_LOOP;
1430 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1432 const char *name = talloc_get_name(ptr);
1433 FILE *f = (FILE *)_f;
1436 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1441 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1442 (max_depth < 0 ? "full " :""), name,
1443 (unsigned long)talloc_total_size(ptr),
1444 (unsigned long)talloc_total_blocks(ptr));
1448 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1451 (unsigned long)talloc_total_size(ptr),
1452 (unsigned long)talloc_total_blocks(ptr),
1453 (int)talloc_reference_count(ptr), ptr);
1456 fprintf(f, "content: ");
1457 if (talloc_total_size(ptr)) {
1458 int tot = talloc_total_size(ptr);
1461 for (i = 0; i < tot; i++) {
1462 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1463 fprintf(f, "%c", ((char *)ptr)[i]);
1465 fprintf(f, "~%02x", ((char *)ptr)[i]);
1474 report on memory usage by all children of a pointer, giving a full tree view
1476 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1479 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1485 report on memory usage by all children of a pointer, giving a full tree view
1487 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
1489 talloc_report_depth_file(ptr, 0, -1, f);
1493 report on memory usage by all children of a pointer
1495 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
1497 talloc_report_depth_file(ptr, 0, 1, f);
1501 report on any memory hanging off the null context
1503 static void talloc_report_null(void)
1505 if (talloc_total_size(null_context) != 0) {
1506 talloc_report(null_context, stderr);
1511 report on any memory hanging off the null context
1513 static void talloc_report_null_full(void)
1515 if (talloc_total_size(null_context) != 0) {
1516 talloc_report_full(null_context, stderr);
1521 enable tracking of the NULL context
1523 _PUBLIC_ void talloc_enable_null_tracking(void)
1525 if (null_context == NULL) {
1526 null_context = _talloc_named_const(NULL, 0, "null_context");
1527 if (autofree_context != NULL) {
1528 talloc_reparent(NULL, null_context, autofree_context);
1534 enable tracking of the NULL context, not moving the autofree context
1535 into the NULL context. This is needed for the talloc testsuite
1537 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
1539 if (null_context == NULL) {
1540 null_context = _talloc_named_const(NULL, 0, "null_context");
1545 disable tracking of the NULL context
1547 _PUBLIC_ void talloc_disable_null_tracking(void)
1549 if (null_context != NULL) {
1550 /* we have to move any children onto the real NULL
1552 struct talloc_chunk *tc, *tc2;
1553 tc = talloc_chunk_from_ptr(null_context);
1554 for (tc2 = tc->child; tc2; tc2=tc2->next) {
1555 if (tc2->parent == tc) tc2->parent = NULL;
1556 if (tc2->prev == tc) tc2->prev = NULL;
1558 for (tc2 = tc->next; tc2; tc2=tc2->next) {
1559 if (tc2->parent == tc) tc2->parent = NULL;
1560 if (tc2->prev == tc) tc2->prev = NULL;
1565 talloc_free(null_context);
1566 null_context = NULL;
1570 enable leak reporting on exit
1572 _PUBLIC_ void talloc_enable_leak_report(void)
1574 talloc_enable_null_tracking();
1575 atexit(talloc_report_null);
1579 enable full leak reporting on exit
1581 _PUBLIC_ void talloc_enable_leak_report_full(void)
1583 talloc_enable_null_tracking();
1584 atexit(talloc_report_null_full);
1588 talloc and zero memory.
1590 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
1592 void *p = _talloc_named_const(ctx, size, name);
1595 memset(p, '\0', size);
1602 memdup with a talloc.
1604 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1606 void *newp = _talloc_named_const(t, size, name);
1609 memcpy(newp, p, size);
1615 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1619 ret = (char *)__talloc(t, len + 1);
1620 if (unlikely(!ret)) return NULL;
1622 memcpy(ret, p, len);
1625 _talloc_set_name_const(ret, ret);
1630 strdup with a talloc
1632 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
1634 if (unlikely(!p)) return NULL;
1635 return __talloc_strlendup(t, p, strlen(p));
1639 strndup with a talloc
1641 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
1643 if (unlikely(!p)) return NULL;
1644 return __talloc_strlendup(t, p, strnlen(p, n));
1647 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1648 const char *a, size_t alen)
1652 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1653 if (unlikely(!ret)) return NULL;
1655 /* append the string and the trailing \0 */
1656 memcpy(&ret[slen], a, alen);
1659 _talloc_set_name_const(ret, ret);
1664 * Appends at the end of the string.
1666 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
1669 return talloc_strdup(NULL, a);
1676 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1680 * Appends at the end of the talloc'ed buffer,
1681 * not the end of the string.
1683 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
1688 return talloc_strdup(NULL, a);
1695 slen = talloc_get_size(s);
1696 if (likely(slen > 0)) {
1700 return __talloc_strlendup_append(s, slen, a, strlen(a));
1704 * Appends at the end of the string.
1706 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
1709 return talloc_strdup(NULL, a);
1716 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1720 * Appends at the end of the talloc'ed buffer,
1721 * not the end of the string.
1723 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1728 return talloc_strdup(NULL, a);
1735 slen = talloc_get_size(s);
1736 if (likely(slen > 0)) {
1740 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1743 #ifndef HAVE_VA_COPY
1744 #ifdef HAVE___VA_COPY
1745 #define va_copy(dest, src) __va_copy(dest, src)
1747 #define va_copy(dest, src) (dest) = (src)
1751 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1758 /* this call looks strange, but it makes it work on older solaris boxes */
1760 len = vsnprintf(&c, 1, fmt, ap2);
1762 if (unlikely(len < 0)) {
1766 ret = (char *)__talloc(t, len+1);
1767 if (unlikely(!ret)) return NULL;
1770 vsnprintf(ret, len+1, fmt, ap2);
1773 _talloc_set_name_const(ret, ret);
1779 Perform string formatting, and return a pointer to newly allocated
1780 memory holding the result, inside a memory pool.
1782 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
1788 ret = talloc_vasprintf(t, fmt, ap);
1793 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1794 const char *fmt, va_list ap)
1795 PRINTF_ATTRIBUTE(3,0);
1797 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1798 const char *fmt, va_list ap)
1805 alen = vsnprintf(&c, 1, fmt, ap2);
1809 /* Either the vsnprintf failed or the format resulted in
1810 * no characters being formatted. In the former case, we
1811 * ought to return NULL, in the latter we ought to return
1812 * the original string. Most current callers of this
1813 * function expect it to never return NULL.
1818 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1819 if (!s) return NULL;
1822 vsnprintf(s + slen, alen + 1, fmt, ap2);
1825 _talloc_set_name_const(s, s);
1830 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1831 * and return @p s, which may have moved. Good for gradually
1832 * accumulating output into a string buffer. Appends at the end
1835 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1838 return talloc_vasprintf(NULL, fmt, ap);
1841 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1845 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1846 * and return @p s, which may have moved. Always appends at the
1847 * end of the talloc'ed buffer, not the end of the string.
1849 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1854 return talloc_vasprintf(NULL, fmt, ap);
1857 slen = talloc_get_size(s);
1858 if (likely(slen > 0)) {
1862 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1866 Realloc @p s to append the formatted result of @p fmt and return @p
1867 s, which may have moved. Good for gradually accumulating output
1868 into a string buffer.
1870 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
1875 s = talloc_vasprintf_append(s, fmt, ap);
1881 Realloc @p s to append the formatted result of @p fmt and return @p
1882 s, which may have moved. Good for gradually accumulating output
1885 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1890 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1896 alloc an array, checking for integer overflow in the array size
1898 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1900 if (count >= MAX_TALLOC_SIZE/el_size) {
1903 return _talloc_named_const(ctx, el_size * count, name);
1907 alloc an zero array, checking for integer overflow in the array size
1909 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1911 if (count >= MAX_TALLOC_SIZE/el_size) {
1914 return _talloc_zero(ctx, el_size * count, name);
1918 realloc an array, checking for integer overflow in the array size
1920 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1922 if (count >= MAX_TALLOC_SIZE/el_size) {
1925 return _talloc_realloc(ctx, ptr, el_size * count, name);
1929 a function version of talloc_realloc(), so it can be passed as a function pointer
1930 to libraries that want a realloc function (a realloc function encapsulates
1931 all the basic capabilities of an allocation library, which is why this is useful)
1933 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1935 return _talloc_realloc(context, ptr, size, NULL);
1939 static int talloc_autofree_destructor(void *ptr)
1941 autofree_context = NULL;
1945 static void talloc_autofree(void)
1947 talloc_free(autofree_context);
1951 return a context which will be auto-freed on exit
1952 this is useful for reducing the noise in leak reports
1954 _PUBLIC_ void *talloc_autofree_context(void)
1956 if (autofree_context == NULL) {
1957 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1958 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1959 atexit(talloc_autofree);
1961 return autofree_context;
1964 _PUBLIC_ size_t talloc_get_size(const void *context)
1966 struct talloc_chunk *tc;
1968 if (context == NULL) {
1969 context = null_context;
1971 if (context == NULL) {
1975 tc = talloc_chunk_from_ptr(context);
1981 find a parent of this context that has the given name, if any
1983 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
1985 struct talloc_chunk *tc;
1987 if (context == NULL) {
1991 tc = talloc_chunk_from_ptr(context);
1993 if (tc->name && strcmp(tc->name, name) == 0) {
1994 return TC_PTR_FROM_CHUNK(tc);
1996 while (tc && tc->prev) tc = tc->prev;
2005 show the parentage of a context
2007 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2009 struct talloc_chunk *tc;
2011 if (context == NULL) {
2012 fprintf(file, "talloc no parents for NULL\n");
2016 tc = talloc_chunk_from_ptr(context);
2017 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
2019 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2020 while (tc && tc->prev) tc = tc->prev;
2029 return 1 if ptr is a parent of context
2031 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2033 struct talloc_chunk *tc;
2035 if (context == NULL) {
2039 tc = talloc_chunk_from_ptr(context);
2040 while (tc && depth > 0) {
2041 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2042 while (tc && tc->prev) tc = tc->prev;
2052 return 1 if ptr is a parent of context
2054 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2056 return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);