s3:passdb: fix and improve debug message in pdb_default_sid_to_id().
[Samba.git] / lib / talloc / talloc.c
blob1cb4d7dead792dad9bf362a1fb1025b3f802767d
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 #include "replace.h"
34 #include "talloc.h"
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
39 #endif
40 #endif
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
45 #endif
46 #endif
48 /* Special macros that are no-ops except when run under Valgrind on
49 * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
50 #ifdef HAVE_VALGRIND_MEMCHECK_H
51 /* memcheck.h includes valgrind.h */
52 #include <valgrind/memcheck.h>
53 #elif defined(HAVE_VALGRIND_H)
54 #include <valgrind.h>
55 #endif
57 /* use this to force every realloc to change the pointer, to stress test
58 code that might not cope */
59 #define ALWAYS_REALLOC 0
62 #define MAX_TALLOC_SIZE 0x10000000
63 #define TALLOC_MAGIC_BASE 0xe814ec70
64 #define TALLOC_MAGIC ( \
65 TALLOC_MAGIC_BASE + \
66 (TALLOC_VERSION_MAJOR << 12) + \
67 (TALLOC_VERSION_MINOR << 4) \
70 #define TALLOC_FLAG_FREE 0x01
71 #define TALLOC_FLAG_LOOP 0x02
72 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
73 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
75 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
77 /* by default we abort when given a bad pointer (such as when talloc_free() is called
78 on a pointer that came from malloc() */
79 #ifndef TALLOC_ABORT
80 #define TALLOC_ABORT(reason) abort()
81 #endif
83 #ifndef discard_const_p
84 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
85 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
86 #else
87 # define discard_const_p(type, ptr) ((type *)(ptr))
88 #endif
89 #endif
91 /* these macros gain us a few percent of speed on gcc */
92 #if (__GNUC__ >= 3)
93 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
94 as its first argument */
95 #ifndef likely
96 #define likely(x) __builtin_expect(!!(x), 1)
97 #endif
98 #ifndef unlikely
99 #define unlikely(x) __builtin_expect(!!(x), 0)
100 #endif
101 #else
102 #ifndef likely
103 #define likely(x) (x)
104 #endif
105 #ifndef unlikely
106 #define unlikely(x) (x)
107 #endif
108 #endif
110 /* this null_context is only used if talloc_enable_leak_report() or
111 talloc_enable_leak_report_full() is called, otherwise it remains
112 NULL
114 static void *null_context;
115 static void *autofree_context;
117 /* used to enable fill of memory on free, which can be useful for
118 * catching use after free errors when valgrind is too slow
120 static struct {
121 bool initialised;
122 bool enabled;
123 uint8_t fill_value;
124 } talloc_fill;
126 #define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
129 * do not wipe the header, to allow the
130 * double-free logic to still work
132 #define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \
133 if (unlikely(talloc_fill.enabled)) { \
134 size_t _flen = (_tc)->size; \
135 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
136 memset(_fptr, talloc_fill.fill_value, _flen); \
138 } while (0)
140 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
141 /* Mark the whole chunk as not accessable */
142 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \
143 size_t _flen = TC_HDR_SIZE + (_tc)->size; \
144 char *_fptr = (char *)(_tc); \
145 VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
146 } while(0)
147 #else
148 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0)
149 #endif
151 #define TC_INVALIDATE_FULL_CHUNK(_tc) do { \
152 TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \
153 TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \
154 } while (0)
156 #define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
157 if (unlikely(talloc_fill.enabled)) { \
158 size_t _flen = (_tc)->size - (_new_size); \
159 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
160 _fptr += (_new_size); \
161 memset(_fptr, talloc_fill.fill_value, _flen); \
163 } while (0)
165 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
166 /* Mark the unused bytes not accessable */
167 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
168 size_t _flen = (_tc)->size - (_new_size); \
169 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
170 _fptr += (_new_size); \
171 VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
172 } while (0)
173 #else
174 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
175 #endif
177 #define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \
178 TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \
179 TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
180 } while (0)
182 #define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
183 if (unlikely(talloc_fill.enabled)) { \
184 size_t _flen = (_tc)->size - (_new_size); \
185 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
186 _fptr += (_new_size); \
187 memset(_fptr, talloc_fill.fill_value, _flen); \
189 } while (0)
191 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
192 /* Mark the unused bytes as undefined */
193 #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
194 size_t _flen = (_tc)->size - (_new_size); \
195 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
196 _fptr += (_new_size); \
197 VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
198 } while (0)
199 #else
200 #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
201 #endif
203 #define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \
204 TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \
205 TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
206 } while (0)
208 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
209 /* Mark the new bytes as undefined */
210 #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \
211 size_t _old_used = TC_HDR_SIZE + (_tc)->size; \
212 size_t _new_used = TC_HDR_SIZE + (_new_size); \
213 size_t _flen = _new_used - _old_used; \
214 char *_fptr = _old_used + (char *)(_tc); \
215 VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
216 } while (0)
217 #else
218 #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
219 #endif
221 #define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \
222 TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \
223 } while (0)
225 struct talloc_reference_handle {
226 struct talloc_reference_handle *next, *prev;
227 void *ptr;
228 const char *location;
231 struct talloc_memlimit {
232 struct talloc_chunk *parent;
233 struct talloc_memlimit *upper;
234 size_t max_size;
235 size_t cur_size;
238 static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
239 static void talloc_memlimit_grow(struct talloc_memlimit *limit,
240 size_t size);
241 static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
242 size_t size);
243 static void talloc_memlimit_update_on_free(struct talloc_chunk *tc);
245 typedef int (*talloc_destructor_t)(void *);
247 struct talloc_pool_hdr;
249 struct talloc_chunk {
250 struct talloc_chunk *next, *prev;
251 struct talloc_chunk *parent, *child;
252 struct talloc_reference_handle *refs;
253 talloc_destructor_t destructor;
254 const char *name;
255 size_t size;
256 unsigned flags;
259 * limit semantics:
260 * if 'limit' is set it means all *new* children of the context will
261 * be limited to a total aggregate size ox max_size for memory
262 * allocations.
263 * cur_size is used to keep track of the current use
265 struct talloc_memlimit *limit;
268 * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
269 * is a pointer to the struct talloc_chunk of the pool that it was
270 * allocated from. This way children can quickly find the pool to chew
271 * from.
273 struct talloc_pool_hdr *pool;
276 /* 16 byte alignment seems to keep everyone happy */
277 #define TC_ALIGN16(s) (((s)+15)&~15)
278 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
279 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
281 _PUBLIC_ int talloc_version_major(void)
283 return TALLOC_VERSION_MAJOR;
286 _PUBLIC_ int talloc_version_minor(void)
288 return TALLOC_VERSION_MINOR;
291 static void (*talloc_log_fn)(const char *message);
293 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
295 talloc_log_fn = log_fn;
298 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
299 static void talloc_log(const char *fmt, ...)
301 va_list ap;
302 char *message;
304 if (!talloc_log_fn) {
305 return;
308 va_start(ap, fmt);
309 message = talloc_vasprintf(NULL, fmt, ap);
310 va_end(ap);
312 talloc_log_fn(message);
313 talloc_free(message);
316 static void talloc_log_stderr(const char *message)
318 fprintf(stderr, "%s", message);
321 _PUBLIC_ void talloc_set_log_stderr(void)
323 talloc_set_log_fn(talloc_log_stderr);
326 static void (*talloc_abort_fn)(const char *reason);
328 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
330 talloc_abort_fn = abort_fn;
333 static void talloc_abort(const char *reason)
335 talloc_log("%s\n", reason);
337 if (!talloc_abort_fn) {
338 TALLOC_ABORT(reason);
341 talloc_abort_fn(reason);
344 static void talloc_abort_magic(unsigned magic)
346 unsigned striped = magic - TALLOC_MAGIC_BASE;
347 unsigned major = (striped & 0xFFFFF000) >> 12;
348 unsigned minor = (striped & 0x00000FF0) >> 4;
349 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
350 magic, major, minor,
351 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
352 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
355 static void talloc_abort_access_after_free(void)
357 talloc_abort("Bad talloc magic value - access after free");
360 static void talloc_abort_unknown_value(void)
362 talloc_abort("Bad talloc magic value - unknown value");
365 /* panic if we get a bad magic value */
366 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
368 const char *pp = (const char *)ptr;
369 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
370 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
371 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
372 talloc_abort_magic(tc->flags & (~0xF));
373 return NULL;
376 if (tc->flags & TALLOC_FLAG_FREE) {
377 talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
378 talloc_abort_access_after_free();
379 return NULL;
380 } else {
381 talloc_abort_unknown_value();
382 return NULL;
385 return tc;
388 /* hook into the front of the list */
389 #define _TLIST_ADD(list, p) \
390 do { \
391 if (!(list)) { \
392 (list) = (p); \
393 (p)->next = (p)->prev = NULL; \
394 } else { \
395 (list)->prev = (p); \
396 (p)->next = (list); \
397 (p)->prev = NULL; \
398 (list) = (p); \
400 } while (0)
402 /* remove an element from a list - element doesn't have to be in list. */
403 #define _TLIST_REMOVE(list, p) \
404 do { \
405 if ((p) == (list)) { \
406 (list) = (p)->next; \
407 if (list) (list)->prev = NULL; \
408 } else { \
409 if ((p)->prev) (p)->prev->next = (p)->next; \
410 if ((p)->next) (p)->next->prev = (p)->prev; \
412 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
413 } while (0)
417 return the parent chunk of a pointer
419 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
421 struct talloc_chunk *tc;
423 if (unlikely(ptr == NULL)) {
424 return NULL;
427 tc = talloc_chunk_from_ptr(ptr);
428 while (tc->prev) tc=tc->prev;
430 return tc->parent;
433 _PUBLIC_ void *talloc_parent(const void *ptr)
435 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
436 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
440 find parents name
442 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
444 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
445 return tc? tc->name : NULL;
449 A pool carries an in-pool object count count in the first 16 bytes.
450 bytes. This is done to support talloc_steal() to a parent outside of the
451 pool. The count includes the pool itself, so a talloc_free() on a pool will
452 only destroy the pool if the count has dropped to zero. A talloc_free() of a
453 pool member will reduce the count, and eventually also call free(3) on the
454 pool memory.
456 The object count is not put into "struct talloc_chunk" because it is only
457 relevant for talloc pools and the alignment to 16 bytes would increase the
458 memory footprint of each talloc chunk by those 16 bytes.
461 struct talloc_pool_hdr {
462 void *end;
463 unsigned int object_count;
464 size_t poolsize;
467 #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr))
469 static struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c)
471 return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE);
474 static struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h)
476 return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE);
479 static void *tc_pool_end(struct talloc_pool_hdr *pool_hdr)
481 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
482 return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize;
485 static size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr)
487 return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end;
490 /* If tc is inside a pool, this gives the next neighbour. */
491 static void *tc_next_chunk(struct talloc_chunk *tc)
493 return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
496 static void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr)
498 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
499 return tc_next_chunk(tc);
502 /* Mark the whole remaining pool as not accessable */
503 static void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr)
505 size_t flen = tc_pool_space_left(pool_hdr);
507 if (unlikely(talloc_fill.enabled)) {
508 memset(pool_hdr->end, talloc_fill.fill_value, flen);
511 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
512 VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen);
513 #endif
517 Allocate from a pool
520 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
521 size_t size, size_t prefix_len)
523 struct talloc_pool_hdr *pool_hdr = NULL;
524 size_t space_left;
525 struct talloc_chunk *result;
526 size_t chunk_size;
528 if (parent == NULL) {
529 return NULL;
532 if (parent->flags & TALLOC_FLAG_POOL) {
533 pool_hdr = talloc_pool_from_chunk(parent);
535 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
536 pool_hdr = parent->pool;
539 if (pool_hdr == NULL) {
540 return NULL;
543 space_left = tc_pool_space_left(pool_hdr);
546 * Align size to 16 bytes
548 chunk_size = TC_ALIGN16(size + prefix_len);
550 if (space_left < chunk_size) {
551 return NULL;
554 result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len);
556 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
557 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size);
558 #endif
560 pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size);
562 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
563 result->pool = pool_hdr;
565 pool_hdr->object_count++;
567 return result;
571 Allocate a bit of memory as a child of an existing pointer
573 static inline void *__talloc_with_prefix(const void *context, size_t size,
574 size_t prefix_len)
576 struct talloc_chunk *tc = NULL;
577 struct talloc_memlimit *limit = NULL;
578 size_t total_len = TC_HDR_SIZE + size + prefix_len;
580 if (unlikely(context == NULL)) {
581 context = null_context;
584 if (unlikely(size >= MAX_TALLOC_SIZE)) {
585 return NULL;
588 if (unlikely(total_len < TC_HDR_SIZE)) {
589 return NULL;
592 if (context != NULL) {
593 struct talloc_chunk *ptc = talloc_chunk_from_ptr(context);
595 if (ptc->limit != NULL) {
596 limit = ptc->limit;
599 tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len);
602 if (tc == NULL) {
603 char *ptr;
606 * Only do the memlimit check/update on actual allocation.
608 if (!talloc_memlimit_check(limit, total_len)) {
609 errno = ENOMEM;
610 return NULL;
613 ptr = malloc(total_len);
614 if (unlikely(ptr == NULL)) {
615 return NULL;
617 tc = (struct talloc_chunk *)(ptr + prefix_len);
618 tc->flags = TALLOC_MAGIC;
619 tc->pool = NULL;
621 talloc_memlimit_grow(limit, total_len);
624 tc->limit = limit;
625 tc->size = size;
626 tc->destructor = NULL;
627 tc->child = NULL;
628 tc->name = NULL;
629 tc->refs = NULL;
631 if (likely(context)) {
632 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
634 if (parent->child) {
635 parent->child->parent = NULL;
636 tc->next = parent->child;
637 tc->next->prev = tc;
638 } else {
639 tc->next = NULL;
641 tc->parent = parent;
642 tc->prev = NULL;
643 parent->child = tc;
644 } else {
645 tc->next = tc->prev = tc->parent = NULL;
648 return TC_PTR_FROM_CHUNK(tc);
651 static inline void *__talloc(const void *context, size_t size)
653 return __talloc_with_prefix(context, size, 0);
657 * Create a talloc pool
660 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
662 struct talloc_chunk *tc;
663 struct talloc_pool_hdr *pool_hdr;
664 void *result;
666 result = __talloc_with_prefix(context, size, TP_HDR_SIZE);
668 if (unlikely(result == NULL)) {
669 return NULL;
672 tc = talloc_chunk_from_ptr(result);
673 pool_hdr = talloc_pool_from_chunk(tc);
675 tc->flags |= TALLOC_FLAG_POOL;
676 tc->size = 0;
678 pool_hdr->object_count = 1;
679 pool_hdr->end = result;
680 pool_hdr->poolsize = size;
682 tc_invalidate_pool(pool_hdr);
684 return result;
688 * Create a talloc pool correctly sized for a basic size plus
689 * a number of subobjects whose total size is given. Essentially
690 * a custom allocator for talloc to reduce fragmentation.
693 _PUBLIC_ void *_talloc_pooled_object(const void *ctx,
694 size_t type_size,
695 const char *type_name,
696 unsigned num_subobjects,
697 size_t total_subobjects_size)
699 size_t poolsize, subobjects_slack, tmp;
700 struct talloc_chunk *tc;
701 struct talloc_pool_hdr *pool_hdr;
702 void *ret;
704 poolsize = type_size + total_subobjects_size;
706 if ((poolsize < type_size) || (poolsize < total_subobjects_size)) {
707 goto overflow;
710 if (num_subobjects == UINT_MAX) {
711 goto overflow;
713 num_subobjects += 1; /* the object body itself */
716 * Alignment can increase the pool size by at most 15 bytes per object
717 * plus alignment for the object itself
719 subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects;
720 if (subobjects_slack < num_subobjects) {
721 goto overflow;
724 tmp = poolsize + subobjects_slack;
725 if ((tmp < poolsize) || (tmp < subobjects_slack)) {
726 goto overflow;
728 poolsize = tmp;
730 ret = talloc_pool(ctx, poolsize);
731 if (ret == NULL) {
732 return NULL;
735 tc = talloc_chunk_from_ptr(ret);
736 tc->size = type_size;
738 pool_hdr = talloc_pool_from_chunk(tc);
740 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
741 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size);
742 #endif
744 pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size));
746 talloc_set_name_const(ret, type_name);
747 return ret;
749 overflow:
750 return NULL;
754 setup a destructor to be called on free of a pointer
755 the destructor should return 0 on success, or -1 on failure.
756 if the destructor fails then the free is failed, and the memory can
757 be continued to be used
759 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
761 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
762 tc->destructor = destructor;
766 increase the reference count on a piece of memory.
768 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
770 if (unlikely(!talloc_reference(null_context, ptr))) {
771 return -1;
773 return 0;
777 helper for talloc_reference()
779 this is referenced by a function pointer and should not be inline
781 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
783 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
784 _TLIST_REMOVE(ptr_tc->refs, handle);
785 return 0;
789 more efficient way to add a name to a pointer - the name must point to a
790 true string constant
792 static inline void _talloc_set_name_const(const void *ptr, const char *name)
794 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
795 tc->name = name;
799 internal talloc_named_const()
801 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
803 void *ptr;
805 ptr = __talloc(context, size);
806 if (unlikely(ptr == NULL)) {
807 return NULL;
810 _talloc_set_name_const(ptr, name);
812 return ptr;
816 make a secondary reference to a pointer, hanging off the given context.
817 the pointer remains valid until both the original caller and this given
818 context are freed.
820 the major use for this is when two different structures need to reference the
821 same underlying data, and you want to be able to free the two instances separately,
822 and in either order
824 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
826 struct talloc_chunk *tc;
827 struct talloc_reference_handle *handle;
828 if (unlikely(ptr == NULL)) return NULL;
830 tc = talloc_chunk_from_ptr(ptr);
831 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
832 sizeof(struct talloc_reference_handle),
833 TALLOC_MAGIC_REFERENCE);
834 if (unlikely(handle == NULL)) return NULL;
836 /* note that we hang the destructor off the handle, not the
837 main context as that allows the caller to still setup their
838 own destructor on the context if they want to */
839 talloc_set_destructor(handle, talloc_reference_destructor);
840 handle->ptr = discard_const_p(void, ptr);
841 handle->location = location;
842 _TLIST_ADD(tc->refs, handle);
843 return handle->ptr;
846 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
848 static inline void _talloc_free_poolmem(struct talloc_chunk *tc,
849 const char *location)
851 struct talloc_pool_hdr *pool;
852 struct talloc_chunk *pool_tc;
853 void *next_tc;
855 pool = tc->pool;
856 pool_tc = talloc_chunk_from_pool(pool);
857 next_tc = tc_next_chunk(tc);
859 tc->flags |= TALLOC_FLAG_FREE;
861 /* we mark the freed memory with where we called the free
862 * from. This means on a double free error we can report where
863 * the first free came from
865 tc->name = location;
867 TC_INVALIDATE_FULL_CHUNK(tc);
869 if (unlikely(pool->object_count == 0)) {
870 talloc_abort("Pool object count zero!");
871 return;
874 pool->object_count--;
876 if (unlikely(pool->object_count == 1
877 && !(pool_tc->flags & TALLOC_FLAG_FREE))) {
879 * if there is just one object left in the pool
880 * and pool->flags does not have TALLOC_FLAG_FREE,
881 * it means this is the pool itself and
882 * the rest is available for new objects
883 * again.
885 pool->end = tc_pool_first_chunk(pool);
886 tc_invalidate_pool(pool);
887 return;
890 if (unlikely(pool->object_count == 0)) {
892 * we mark the freed memory with where we called the free
893 * from. This means on a double free error we can report where
894 * the first free came from
896 pool_tc->name = location;
898 if (pool_tc->flags & TALLOC_FLAG_POOLMEM) {
899 _talloc_free_poolmem(pool_tc, location);
900 } else {
902 * The talloc_memlimit_update_on_free()
903 * call takes into account the
904 * prefix TP_HDR_SIZE allocated before
905 * the pool talloc_chunk.
907 talloc_memlimit_update_on_free(pool_tc);
908 TC_INVALIDATE_FULL_CHUNK(pool_tc);
909 free(pool);
911 return;
914 if (pool->end == next_tc) {
916 * if pool->pool still points to end of
917 * 'tc' (which is stored in the 'next_tc' variable),
918 * we can reclaim the memory of 'tc'.
920 pool->end = tc;
921 return;
925 * Do nothing. The memory is just "wasted", waiting for the pool
926 * itself to be freed.
930 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
931 void *ptr,
932 const char *location);
935 internal talloc_free call
937 static inline int _talloc_free_internal(void *ptr, const char *location)
939 struct talloc_chunk *tc;
940 void *ptr_to_free;
942 if (unlikely(ptr == NULL)) {
943 return -1;
946 /* possibly initialised the talloc fill value */
947 if (unlikely(!talloc_fill.initialised)) {
948 const char *fill = getenv(TALLOC_FILL_ENV);
949 if (fill != NULL) {
950 talloc_fill.enabled = true;
951 talloc_fill.fill_value = strtoul(fill, NULL, 0);
953 talloc_fill.initialised = true;
956 tc = talloc_chunk_from_ptr(ptr);
958 if (unlikely(tc->refs)) {
959 int is_child;
960 /* check if this is a reference from a child or
961 * grandchild back to it's parent or grandparent
963 * in that case we need to remove the reference and
964 * call another instance of talloc_free() on the current
965 * pointer.
967 is_child = talloc_is_parent(tc->refs, ptr);
968 _talloc_free_internal(tc->refs, location);
969 if (is_child) {
970 return _talloc_free_internal(ptr, location);
972 return -1;
975 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
976 /* we have a free loop - stop looping */
977 return 0;
980 if (unlikely(tc->destructor)) {
981 talloc_destructor_t d = tc->destructor;
982 if (d == (talloc_destructor_t)-1) {
983 return -1;
985 tc->destructor = (talloc_destructor_t)-1;
986 if (d(ptr) == -1) {
987 tc->destructor = d;
988 return -1;
990 tc->destructor = NULL;
993 if (tc->parent) {
994 _TLIST_REMOVE(tc->parent->child, tc);
995 if (tc->parent->child) {
996 tc->parent->child->parent = tc->parent;
998 } else {
999 if (tc->prev) tc->prev->next = tc->next;
1000 if (tc->next) tc->next->prev = tc->prev;
1001 tc->prev = tc->next = NULL;
1004 tc->flags |= TALLOC_FLAG_LOOP;
1006 _talloc_free_children_internal(tc, ptr, location);
1008 tc->flags |= TALLOC_FLAG_FREE;
1010 /* we mark the freed memory with where we called the free
1011 * from. This means on a double free error we can report where
1012 * the first free came from
1014 tc->name = location;
1016 if (tc->flags & TALLOC_FLAG_POOL) {
1017 struct talloc_pool_hdr *pool;
1019 pool = talloc_pool_from_chunk(tc);
1021 if (unlikely(pool->object_count == 0)) {
1022 talloc_abort("Pool object count zero!");
1023 return 0;
1026 pool->object_count--;
1028 if (likely(pool->object_count != 0)) {
1029 return 0;
1033 * With object_count==0, a pool becomes a normal piece of
1034 * memory to free. If it's allocated inside a pool, it needs
1035 * to be freed as poolmem, else it needs to be just freed.
1037 ptr_to_free = pool;
1038 } else {
1039 ptr_to_free = tc;
1042 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1043 _talloc_free_poolmem(tc, location);
1044 return 0;
1047 talloc_memlimit_update_on_free(tc);
1049 TC_INVALIDATE_FULL_CHUNK(tc);
1050 free(ptr_to_free);
1051 return 0;
1054 static size_t _talloc_total_limit_size(const void *ptr,
1055 struct talloc_memlimit *old_limit,
1056 struct talloc_memlimit *new_limit);
1059 move a lump of memory from one talloc context to another return the
1060 ptr on success, or NULL if it could not be transferred.
1061 passing NULL as ptr will always return NULL with no side effects.
1063 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
1065 struct talloc_chunk *tc, *new_tc;
1066 size_t ctx_size = 0;
1068 if (unlikely(!ptr)) {
1069 return NULL;
1072 if (unlikely(new_ctx == NULL)) {
1073 new_ctx = null_context;
1076 tc = talloc_chunk_from_ptr(ptr);
1078 if (tc->limit != NULL) {
1080 ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
1082 /* Decrement the memory limit from the source .. */
1083 talloc_memlimit_shrink(tc->limit->upper, ctx_size);
1085 if (tc->limit->parent == tc) {
1086 tc->limit->upper = NULL;
1087 } else {
1088 tc->limit = NULL;
1092 if (unlikely(new_ctx == NULL)) {
1093 if (tc->parent) {
1094 _TLIST_REMOVE(tc->parent->child, tc);
1095 if (tc->parent->child) {
1096 tc->parent->child->parent = tc->parent;
1098 } else {
1099 if (tc->prev) tc->prev->next = tc->next;
1100 if (tc->next) tc->next->prev = tc->prev;
1103 tc->parent = tc->next = tc->prev = NULL;
1104 return discard_const_p(void, ptr);
1107 new_tc = talloc_chunk_from_ptr(new_ctx);
1109 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
1110 return discard_const_p(void, ptr);
1113 if (tc->parent) {
1114 _TLIST_REMOVE(tc->parent->child, tc);
1115 if (tc->parent->child) {
1116 tc->parent->child->parent = tc->parent;
1118 } else {
1119 if (tc->prev) tc->prev->next = tc->next;
1120 if (tc->next) tc->next->prev = tc->prev;
1121 tc->prev = tc->next = NULL;
1124 tc->parent = new_tc;
1125 if (new_tc->child) new_tc->child->parent = NULL;
1126 _TLIST_ADD(new_tc->child, tc);
1128 if (tc->limit || new_tc->limit) {
1129 ctx_size = _talloc_total_limit_size(ptr, tc->limit,
1130 new_tc->limit);
1131 /* .. and increment it in the destination. */
1132 if (new_tc->limit) {
1133 talloc_memlimit_grow(new_tc->limit, ctx_size);
1137 return discard_const_p(void, ptr);
1141 move a lump of memory from one talloc context to another return the
1142 ptr on success, or NULL if it could not be transferred.
1143 passing NULL as ptr will always return NULL with no side effects.
1145 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
1147 struct talloc_chunk *tc;
1149 if (unlikely(ptr == NULL)) {
1150 return NULL;
1153 tc = talloc_chunk_from_ptr(ptr);
1155 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
1156 struct talloc_reference_handle *h;
1158 talloc_log("WARNING: talloc_steal with references at %s\n",
1159 location);
1161 for (h=tc->refs; h; h=h->next) {
1162 talloc_log("\treference at %s\n",
1163 h->location);
1167 #if 0
1168 /* this test is probably too expensive to have on in the
1169 normal build, but it useful for debugging */
1170 if (talloc_is_parent(new_ctx, ptr)) {
1171 talloc_log("WARNING: stealing into talloc child at %s\n", location);
1173 #endif
1175 return _talloc_steal_internal(new_ctx, ptr);
1179 this is like a talloc_steal(), but you must supply the old
1180 parent. This resolves the ambiguity in a talloc_steal() which is
1181 called on a context that has more than one parent (via references)
1183 The old parent can be either a reference or a parent
1185 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
1187 struct talloc_chunk *tc;
1188 struct talloc_reference_handle *h;
1190 if (unlikely(ptr == NULL)) {
1191 return NULL;
1194 if (old_parent == talloc_parent(ptr)) {
1195 return _talloc_steal_internal(new_parent, ptr);
1198 tc = talloc_chunk_from_ptr(ptr);
1199 for (h=tc->refs;h;h=h->next) {
1200 if (talloc_parent(h) == old_parent) {
1201 if (_talloc_steal_internal(new_parent, h) != h) {
1202 return NULL;
1204 return discard_const_p(void, ptr);
1208 /* it wasn't a parent */
1209 return NULL;
1213 remove a secondary reference to a pointer. This undo's what
1214 talloc_reference() has done. The context and pointer arguments
1215 must match those given to a talloc_reference()
1217 static inline int talloc_unreference(const void *context, const void *ptr)
1219 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1220 struct talloc_reference_handle *h;
1222 if (unlikely(context == NULL)) {
1223 context = null_context;
1226 for (h=tc->refs;h;h=h->next) {
1227 struct talloc_chunk *p = talloc_parent_chunk(h);
1228 if (p == NULL) {
1229 if (context == NULL) break;
1230 } else if (TC_PTR_FROM_CHUNK(p) == context) {
1231 break;
1234 if (h == NULL) {
1235 return -1;
1238 return _talloc_free_internal(h, __location__);
1242 remove a specific parent context from a pointer. This is a more
1243 controlled variant of talloc_free()
1245 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
1247 struct talloc_chunk *tc_p, *new_p, *tc_c;
1248 void *new_parent;
1250 if (ptr == NULL) {
1251 return -1;
1254 if (context == NULL) {
1255 context = null_context;
1258 if (talloc_unreference(context, ptr) == 0) {
1259 return 0;
1262 if (context != NULL) {
1263 tc_c = talloc_chunk_from_ptr(context);
1264 } else {
1265 tc_c = NULL;
1267 if (tc_c != talloc_parent_chunk(ptr)) {
1268 return -1;
1271 tc_p = talloc_chunk_from_ptr(ptr);
1273 if (tc_p->refs == NULL) {
1274 return _talloc_free_internal(ptr, __location__);
1277 new_p = talloc_parent_chunk(tc_p->refs);
1278 if (new_p) {
1279 new_parent = TC_PTR_FROM_CHUNK(new_p);
1280 } else {
1281 new_parent = NULL;
1284 if (talloc_unreference(new_parent, ptr) != 0) {
1285 return -1;
1288 _talloc_steal_internal(new_parent, ptr);
1290 return 0;
1294 add a name to an existing pointer - va_list version
1296 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1298 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
1300 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1301 tc->name = talloc_vasprintf(ptr, fmt, ap);
1302 if (likely(tc->name)) {
1303 _talloc_set_name_const(tc->name, ".name");
1305 return tc->name;
1309 add a name to an existing pointer
1311 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1313 const char *name;
1314 va_list ap;
1315 va_start(ap, fmt);
1316 name = talloc_set_name_v(ptr, fmt, ap);
1317 va_end(ap);
1318 return name;
1323 create a named talloc pointer. Any talloc pointer can be named, and
1324 talloc_named() operates just like talloc() except that it allows you
1325 to name the pointer.
1327 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1329 va_list ap;
1330 void *ptr;
1331 const char *name;
1333 ptr = __talloc(context, size);
1334 if (unlikely(ptr == NULL)) return NULL;
1336 va_start(ap, fmt);
1337 name = talloc_set_name_v(ptr, fmt, ap);
1338 va_end(ap);
1340 if (unlikely(name == NULL)) {
1341 _talloc_free_internal(ptr, __location__);
1342 return NULL;
1345 return ptr;
1349 return the name of a talloc ptr, or "UNNAMED"
1351 _PUBLIC_ const char *talloc_get_name(const void *ptr)
1353 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1354 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1355 return ".reference";
1357 if (likely(tc->name)) {
1358 return tc->name;
1360 return "UNNAMED";
1365 check if a pointer has the given name. If it does, return the pointer,
1366 otherwise return NULL
1368 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1370 const char *pname;
1371 if (unlikely(ptr == NULL)) return NULL;
1372 pname = talloc_get_name(ptr);
1373 if (likely(pname == name || strcmp(pname, name) == 0)) {
1374 return discard_const_p(void, ptr);
1376 return NULL;
1379 static void talloc_abort_type_mismatch(const char *location,
1380 const char *name,
1381 const char *expected)
1383 const char *reason;
1385 reason = talloc_asprintf(NULL,
1386 "%s: Type mismatch: name[%s] expected[%s]",
1387 location,
1388 name?name:"NULL",
1389 expected);
1390 if (!reason) {
1391 reason = "Type mismatch";
1394 talloc_abort(reason);
1397 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1399 const char *pname;
1401 if (unlikely(ptr == NULL)) {
1402 talloc_abort_type_mismatch(location, NULL, name);
1403 return NULL;
1406 pname = talloc_get_name(ptr);
1407 if (likely(pname == name || strcmp(pname, name) == 0)) {
1408 return discard_const_p(void, ptr);
1411 talloc_abort_type_mismatch(location, pname, name);
1412 return NULL;
1416 this is for compatibility with older versions of talloc
1418 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1420 va_list ap;
1421 void *ptr;
1422 const char *name;
1424 ptr = __talloc(NULL, 0);
1425 if (unlikely(ptr == NULL)) return NULL;
1427 va_start(ap, fmt);
1428 name = talloc_set_name_v(ptr, fmt, ap);
1429 va_end(ap);
1431 if (unlikely(name == NULL)) {
1432 _talloc_free_internal(ptr, __location__);
1433 return NULL;
1436 return ptr;
1439 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
1440 void *ptr,
1441 const char *location)
1443 while (tc->child) {
1444 /* we need to work out who will own an abandoned child
1445 if it cannot be freed. In priority order, the first
1446 choice is owner of any remaining reference to this
1447 pointer, the second choice is our parent, and the
1448 final choice is the null context. */
1449 void *child = TC_PTR_FROM_CHUNK(tc->child);
1450 const void *new_parent = null_context;
1451 if (unlikely(tc->child->refs)) {
1452 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1453 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1455 if (unlikely(_talloc_free_internal(child, location) == -1)) {
1456 if (new_parent == null_context) {
1457 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1458 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1460 _talloc_steal_internal(new_parent, child);
1466 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1467 should probably not be used in new code. It's in here to keep the talloc
1468 code consistent across Samba 3 and 4.
1470 _PUBLIC_ void talloc_free_children(void *ptr)
1472 struct talloc_chunk *tc_name = NULL;
1473 struct talloc_chunk *tc;
1475 if (unlikely(ptr == NULL)) {
1476 return;
1479 tc = talloc_chunk_from_ptr(ptr);
1481 /* we do not want to free the context name if it is a child .. */
1482 if (likely(tc->child)) {
1483 for (tc_name = tc->child; tc_name; tc_name = tc_name->next) {
1484 if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break;
1486 if (tc_name) {
1487 _TLIST_REMOVE(tc->child, tc_name);
1488 if (tc->child) {
1489 tc->child->parent = tc;
1494 _talloc_free_children_internal(tc, ptr, __location__);
1496 /* .. so we put it back after all other children have been freed */
1497 if (tc_name) {
1498 if (tc->child) {
1499 tc->child->parent = NULL;
1501 tc_name->parent = tc;
1502 _TLIST_ADD(tc->child, tc_name);
1507 Allocate a bit of memory as a child of an existing pointer
1509 _PUBLIC_ void *_talloc(const void *context, size_t size)
1511 return __talloc(context, size);
1515 externally callable talloc_set_name_const()
1517 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1519 _talloc_set_name_const(ptr, name);
1523 create a named talloc pointer. Any talloc pointer can be named, and
1524 talloc_named() operates just like talloc() except that it allows you
1525 to name the pointer.
1527 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1529 return _talloc_named_const(context, size, name);
1533 free a talloc pointer. This also frees all child pointers of this
1534 pointer recursively
1536 return 0 if the memory is actually freed, otherwise -1. The memory
1537 will not be freed if the ref_count is > 1 or the destructor (if
1538 any) returns non-zero
1540 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1542 struct talloc_chunk *tc;
1544 if (unlikely(ptr == NULL)) {
1545 return -1;
1548 tc = talloc_chunk_from_ptr(ptr);
1550 if (unlikely(tc->refs != NULL)) {
1551 struct talloc_reference_handle *h;
1553 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1554 /* in this case we do know which parent should
1555 get this pointer, as there is really only
1556 one parent */
1557 return talloc_unlink(null_context, ptr);
1560 talloc_log("ERROR: talloc_free with references at %s\n",
1561 location);
1563 for (h=tc->refs; h; h=h->next) {
1564 talloc_log("\treference at %s\n",
1565 h->location);
1567 return -1;
1570 return _talloc_free_internal(ptr, location);
1576 A talloc version of realloc. The context argument is only used if
1577 ptr is NULL
1579 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1581 struct talloc_chunk *tc;
1582 void *new_ptr;
1583 bool malloced = false;
1584 struct talloc_pool_hdr *pool_hdr = NULL;
1585 size_t old_size = 0;
1586 size_t new_size = 0;
1588 /* size zero is equivalent to free() */
1589 if (unlikely(size == 0)) {
1590 talloc_unlink(context, ptr);
1591 return NULL;
1594 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1595 return NULL;
1598 /* realloc(NULL) is equivalent to malloc() */
1599 if (ptr == NULL) {
1600 return _talloc_named_const(context, size, name);
1603 tc = talloc_chunk_from_ptr(ptr);
1605 /* don't allow realloc on referenced pointers */
1606 if (unlikely(tc->refs)) {
1607 return NULL;
1610 /* don't let anybody try to realloc a talloc_pool */
1611 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1612 return NULL;
1615 if (tc->limit && (size > tc->size)) {
1616 if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
1617 errno = ENOMEM;
1618 return NULL;
1622 /* handle realloc inside a talloc_pool */
1623 if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1624 pool_hdr = tc->pool;
1627 #if (ALWAYS_REALLOC == 0)
1628 /* don't shrink if we have less than 1k to gain */
1629 if (size < tc->size && tc->limit == NULL) {
1630 if (pool_hdr) {
1631 void *next_tc = tc_next_chunk(tc);
1632 TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1633 tc->size = size;
1634 if (next_tc == pool_hdr->end) {
1635 /* note: tc->size has changed, so this works */
1636 pool_hdr->end = tc_next_chunk(tc);
1638 return ptr;
1639 } else if ((tc->size - size) < 1024) {
1641 * if we call TC_INVALIDATE_SHRINK_CHUNK() here
1642 * we would need to call TC_UNDEFINE_GROW_CHUNK()
1643 * after each realloc call, which slows down
1644 * testing a lot :-(.
1646 * That is why we only mark memory as undefined here.
1648 TC_UNDEFINE_SHRINK_CHUNK(tc, size);
1650 /* do not shrink if we have less than 1k to gain */
1651 tc->size = size;
1652 return ptr;
1654 } else if (tc->size == size) {
1656 * do not change the pointer if it is exactly
1657 * the same size.
1659 return ptr;
1661 #endif
1663 /* by resetting magic we catch users of the old memory */
1664 tc->flags |= TALLOC_FLAG_FREE;
1666 #if ALWAYS_REALLOC
1667 if (pool_hdr) {
1668 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1669 pool_hdr->object_count--;
1671 if (new_ptr == NULL) {
1672 new_ptr = malloc(TC_HDR_SIZE+size);
1673 malloced = true;
1674 new_size = size;
1677 if (new_ptr) {
1678 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1679 TC_INVALIDATE_FULL_CHUNK(tc);
1681 } else {
1682 /* We're doing malloc then free here, so record the difference. */
1683 old_size = tc->size;
1684 new_size = size;
1685 new_ptr = malloc(size + TC_HDR_SIZE);
1686 if (new_ptr) {
1687 memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1688 free(tc);
1691 #else
1692 if (pool_hdr) {
1693 struct talloc_chunk *pool_tc;
1694 void *next_tc = tc_next_chunk(tc);
1695 size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
1696 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1697 size_t space_needed;
1698 size_t space_left;
1699 unsigned int chunk_count = pool_hdr->object_count;
1701 pool_tc = talloc_chunk_from_pool(pool_hdr);
1702 if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
1703 chunk_count -= 1;
1706 if (chunk_count == 1) {
1708 * optimize for the case where 'tc' is the only
1709 * chunk in the pool.
1711 char *start = tc_pool_first_chunk(pool_hdr);
1712 space_needed = new_chunk_size;
1713 space_left = (char *)tc_pool_end(pool_hdr) - start;
1715 if (space_left >= space_needed) {
1716 size_t old_used = TC_HDR_SIZE + tc->size;
1717 size_t new_used = TC_HDR_SIZE + size;
1718 new_ptr = start;
1720 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1723 * The area from
1724 * start -> tc may have
1725 * been freed and thus been marked as
1726 * VALGRIND_MEM_NOACCESS. Set it to
1727 * VALGRIND_MEM_UNDEFINED so we can
1728 * copy into it without valgrind errors.
1729 * We can't just mark
1730 * new_ptr -> new_ptr + old_used
1731 * as this may overlap on top of tc,
1732 * (which is why we use memmove, not
1733 * memcpy below) hence the MIN.
1735 size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used);
1736 VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len);
1738 #endif
1740 memmove(new_ptr, tc, old_used);
1742 tc = (struct talloc_chunk *)new_ptr;
1743 TC_UNDEFINE_GROW_CHUNK(tc, size);
1746 * first we do not align the pool pointer
1747 * because we want to invalidate the padding
1748 * too.
1750 pool_hdr->end = new_used + (char *)new_ptr;
1751 tc_invalidate_pool(pool_hdr);
1753 /* now the aligned pointer */
1754 pool_hdr->end = new_chunk_size + (char *)new_ptr;
1755 goto got_new_ptr;
1758 next_tc = NULL;
1761 if (new_chunk_size == old_chunk_size) {
1762 TC_UNDEFINE_GROW_CHUNK(tc, size);
1763 tc->flags &= ~TALLOC_FLAG_FREE;
1764 tc->size = size;
1765 return ptr;
1768 if (next_tc == pool_hdr->end) {
1770 * optimize for the case where 'tc' is the last
1771 * chunk in the pool.
1773 space_needed = new_chunk_size - old_chunk_size;
1774 space_left = tc_pool_space_left(pool_hdr);
1776 if (space_left >= space_needed) {
1777 TC_UNDEFINE_GROW_CHUNK(tc, size);
1778 tc->flags &= ~TALLOC_FLAG_FREE;
1779 tc->size = size;
1780 pool_hdr->end = tc_next_chunk(tc);
1781 return ptr;
1785 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1787 if (new_ptr == NULL) {
1788 new_ptr = malloc(TC_HDR_SIZE+size);
1789 malloced = true;
1790 new_size = size;
1793 if (new_ptr) {
1794 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1796 _talloc_free_poolmem(tc, __location__ "_talloc_realloc");
1799 else {
1800 /* We're doing realloc here, so record the difference. */
1801 old_size = tc->size;
1802 new_size = size;
1803 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1805 got_new_ptr:
1806 #endif
1807 if (unlikely(!new_ptr)) {
1808 tc->flags &= ~TALLOC_FLAG_FREE;
1809 return NULL;
1812 tc = (struct talloc_chunk *)new_ptr;
1813 tc->flags &= ~TALLOC_FLAG_FREE;
1814 if (malloced) {
1815 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1817 if (tc->parent) {
1818 tc->parent->child = tc;
1820 if (tc->child) {
1821 tc->child->parent = tc;
1824 if (tc->prev) {
1825 tc->prev->next = tc;
1827 if (tc->next) {
1828 tc->next->prev = tc;
1831 if (new_size > old_size) {
1832 talloc_memlimit_grow(tc->limit, new_size - old_size);
1833 } else if (new_size < old_size) {
1834 talloc_memlimit_shrink(tc->limit, old_size - new_size);
1837 tc->size = size;
1838 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1840 return TC_PTR_FROM_CHUNK(tc);
1844 a wrapper around talloc_steal() for situations where you are moving a pointer
1845 between two structures, and want the old pointer to be set to NULL
1847 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1849 const void **pptr = discard_const_p(const void *,_pptr);
1850 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1851 (*pptr) = NULL;
1852 return ret;
1855 enum talloc_mem_count_type {
1856 TOTAL_MEM_SIZE,
1857 TOTAL_MEM_BLOCKS,
1858 TOTAL_MEM_LIMIT,
1861 static size_t _talloc_total_mem_internal(const void *ptr,
1862 enum talloc_mem_count_type type,
1863 struct talloc_memlimit *old_limit,
1864 struct talloc_memlimit *new_limit)
1866 size_t total = 0;
1867 struct talloc_chunk *c, *tc;
1869 if (ptr == NULL) {
1870 ptr = null_context;
1872 if (ptr == NULL) {
1873 return 0;
1876 tc = talloc_chunk_from_ptr(ptr);
1878 if (old_limit || new_limit) {
1879 if (tc->limit && tc->limit->upper == old_limit) {
1880 tc->limit->upper = new_limit;
1884 /* optimize in the memlimits case */
1885 if (type == TOTAL_MEM_LIMIT &&
1886 tc->limit != NULL &&
1887 tc->limit != old_limit &&
1888 tc->limit->parent == tc) {
1889 return tc->limit->cur_size;
1892 if (tc->flags & TALLOC_FLAG_LOOP) {
1893 return 0;
1896 tc->flags |= TALLOC_FLAG_LOOP;
1898 if (old_limit || new_limit) {
1899 if (old_limit == tc->limit) {
1900 tc->limit = new_limit;
1904 switch (type) {
1905 case TOTAL_MEM_SIZE:
1906 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1907 total = tc->size;
1909 break;
1910 case TOTAL_MEM_BLOCKS:
1911 total++;
1912 break;
1913 case TOTAL_MEM_LIMIT:
1914 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1916 * Don't count memory allocated from a pool
1917 * when calculating limits. Only count the
1918 * pool itself.
1920 if (!(tc->flags & TALLOC_FLAG_POOLMEM)) {
1921 if (tc->flags & TALLOC_FLAG_POOL) {
1923 * If this is a pool, the allocated
1924 * size is in the pool header, and
1925 * remember to add in the prefix
1926 * length.
1928 struct talloc_pool_hdr *pool_hdr
1929 = talloc_pool_from_chunk(tc);
1930 total = pool_hdr->poolsize +
1931 TC_HDR_SIZE +
1932 TP_HDR_SIZE;
1933 } else {
1934 total = tc->size + TC_HDR_SIZE;
1938 break;
1940 for (c = tc->child; c; c = c->next) {
1941 total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type,
1942 old_limit, new_limit);
1945 tc->flags &= ~TALLOC_FLAG_LOOP;
1947 return total;
1951 return the total size of a talloc pool (subtree)
1953 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1955 return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL);
1959 return the total number of blocks in a talloc pool (subtree)
1961 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1963 return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL);
1967 return the number of external references to a pointer
1969 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1971 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1972 struct talloc_reference_handle *h;
1973 size_t ret = 0;
1975 for (h=tc->refs;h;h=h->next) {
1976 ret++;
1978 return ret;
1982 report on memory usage by all children of a pointer, giving a full tree view
1984 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1985 void (*callback)(const void *ptr,
1986 int depth, int max_depth,
1987 int is_ref,
1988 void *private_data),
1989 void *private_data)
1991 struct talloc_chunk *c, *tc;
1993 if (ptr == NULL) {
1994 ptr = null_context;
1996 if (ptr == NULL) return;
1998 tc = talloc_chunk_from_ptr(ptr);
2000 if (tc->flags & TALLOC_FLAG_LOOP) {
2001 return;
2004 callback(ptr, depth, max_depth, 0, private_data);
2006 if (max_depth >= 0 && depth >= max_depth) {
2007 return;
2010 tc->flags |= TALLOC_FLAG_LOOP;
2011 for (c=tc->child;c;c=c->next) {
2012 if (c->name == TALLOC_MAGIC_REFERENCE) {
2013 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
2014 callback(h->ptr, depth + 1, max_depth, 1, private_data);
2015 } else {
2016 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
2019 tc->flags &= ~TALLOC_FLAG_LOOP;
2022 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
2024 const char *name = talloc_get_name(ptr);
2025 struct talloc_chunk *tc;
2026 FILE *f = (FILE *)_f;
2028 if (is_ref) {
2029 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
2030 return;
2033 tc = talloc_chunk_from_ptr(ptr);
2034 if (tc->limit && tc->limit->parent == tc) {
2035 fprintf(f, "%*s%-30s is a memlimit context"
2036 " (max_size = %lu bytes, cur_size = %lu bytes)\n",
2037 depth*4, "",
2038 name,
2039 (unsigned long)tc->limit->max_size,
2040 (unsigned long)tc->limit->cur_size);
2043 if (depth == 0) {
2044 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
2045 (max_depth < 0 ? "full " :""), name,
2046 (unsigned long)talloc_total_size(ptr),
2047 (unsigned long)talloc_total_blocks(ptr));
2048 return;
2051 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
2052 depth*4, "",
2053 name,
2054 (unsigned long)talloc_total_size(ptr),
2055 (unsigned long)talloc_total_blocks(ptr),
2056 (int)talloc_reference_count(ptr), ptr);
2058 #if 0
2059 fprintf(f, "content: ");
2060 if (talloc_total_size(ptr)) {
2061 int tot = talloc_total_size(ptr);
2062 int i;
2064 for (i = 0; i < tot; i++) {
2065 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
2066 fprintf(f, "%c", ((char *)ptr)[i]);
2067 } else {
2068 fprintf(f, "~%02x", ((char *)ptr)[i]);
2072 fprintf(f, "\n");
2073 #endif
2077 report on memory usage by all children of a pointer, giving a full tree view
2079 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
2081 if (f) {
2082 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
2083 fflush(f);
2088 report on memory usage by all children of a pointer, giving a full tree view
2090 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
2092 talloc_report_depth_file(ptr, 0, -1, f);
2096 report on memory usage by all children of a pointer
2098 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
2100 talloc_report_depth_file(ptr, 0, 1, f);
2104 report on any memory hanging off the null context
2106 static void talloc_report_null(void)
2108 if (talloc_total_size(null_context) != 0) {
2109 talloc_report(null_context, stderr);
2114 report on any memory hanging off the null context
2116 static void talloc_report_null_full(void)
2118 if (talloc_total_size(null_context) != 0) {
2119 talloc_report_full(null_context, stderr);
2124 enable tracking of the NULL context
2126 _PUBLIC_ void talloc_enable_null_tracking(void)
2128 if (null_context == NULL) {
2129 null_context = _talloc_named_const(NULL, 0, "null_context");
2130 if (autofree_context != NULL) {
2131 talloc_reparent(NULL, null_context, autofree_context);
2137 enable tracking of the NULL context, not moving the autofree context
2138 into the NULL context. This is needed for the talloc testsuite
2140 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
2142 if (null_context == NULL) {
2143 null_context = _talloc_named_const(NULL, 0, "null_context");
2148 disable tracking of the NULL context
2150 _PUBLIC_ void talloc_disable_null_tracking(void)
2152 if (null_context != NULL) {
2153 /* we have to move any children onto the real NULL
2154 context */
2155 struct talloc_chunk *tc, *tc2;
2156 tc = talloc_chunk_from_ptr(null_context);
2157 for (tc2 = tc->child; tc2; tc2=tc2->next) {
2158 if (tc2->parent == tc) tc2->parent = NULL;
2159 if (tc2->prev == tc) tc2->prev = NULL;
2161 for (tc2 = tc->next; tc2; tc2=tc2->next) {
2162 if (tc2->parent == tc) tc2->parent = NULL;
2163 if (tc2->prev == tc) tc2->prev = NULL;
2165 tc->child = NULL;
2166 tc->next = NULL;
2168 talloc_free(null_context);
2169 null_context = NULL;
2173 enable leak reporting on exit
2175 _PUBLIC_ void talloc_enable_leak_report(void)
2177 talloc_enable_null_tracking();
2178 atexit(talloc_report_null);
2182 enable full leak reporting on exit
2184 _PUBLIC_ void talloc_enable_leak_report_full(void)
2186 talloc_enable_null_tracking();
2187 atexit(talloc_report_null_full);
2191 talloc and zero memory.
2193 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
2195 void *p = _talloc_named_const(ctx, size, name);
2197 if (p) {
2198 memset(p, '\0', size);
2201 return p;
2205 memdup with a talloc.
2207 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
2209 void *newp = _talloc_named_const(t, size, name);
2211 if (likely(newp)) {
2212 memcpy(newp, p, size);
2215 return newp;
2218 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
2220 char *ret;
2222 ret = (char *)__talloc(t, len + 1);
2223 if (unlikely(!ret)) return NULL;
2225 memcpy(ret, p, len);
2226 ret[len] = 0;
2228 _talloc_set_name_const(ret, ret);
2229 return ret;
2233 strdup with a talloc
2235 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
2237 if (unlikely(!p)) return NULL;
2238 return __talloc_strlendup(t, p, strlen(p));
2242 strndup with a talloc
2244 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
2246 if (unlikely(!p)) return NULL;
2247 return __talloc_strlendup(t, p, strnlen(p, n));
2250 static inline char *__talloc_strlendup_append(char *s, size_t slen,
2251 const char *a, size_t alen)
2253 char *ret;
2255 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
2256 if (unlikely(!ret)) return NULL;
2258 /* append the string and the trailing \0 */
2259 memcpy(&ret[slen], a, alen);
2260 ret[slen+alen] = 0;
2262 _talloc_set_name_const(ret, ret);
2263 return ret;
2267 * Appends at the end of the string.
2269 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
2271 if (unlikely(!s)) {
2272 return talloc_strdup(NULL, a);
2275 if (unlikely(!a)) {
2276 return s;
2279 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
2283 * Appends at the end of the talloc'ed buffer,
2284 * not the end of the string.
2286 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
2288 size_t slen;
2290 if (unlikely(!s)) {
2291 return talloc_strdup(NULL, a);
2294 if (unlikely(!a)) {
2295 return s;
2298 slen = talloc_get_size(s);
2299 if (likely(slen > 0)) {
2300 slen--;
2303 return __talloc_strlendup_append(s, slen, a, strlen(a));
2307 * Appends at the end of the string.
2309 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
2311 if (unlikely(!s)) {
2312 return talloc_strndup(NULL, a, n);
2315 if (unlikely(!a)) {
2316 return s;
2319 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
2323 * Appends at the end of the talloc'ed buffer,
2324 * not the end of the string.
2326 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
2328 size_t slen;
2330 if (unlikely(!s)) {
2331 return talloc_strndup(NULL, a, n);
2334 if (unlikely(!a)) {
2335 return s;
2338 slen = talloc_get_size(s);
2339 if (likely(slen > 0)) {
2340 slen--;
2343 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
2346 #ifndef HAVE_VA_COPY
2347 #ifdef HAVE___VA_COPY
2348 #define va_copy(dest, src) __va_copy(dest, src)
2349 #else
2350 #define va_copy(dest, src) (dest) = (src)
2351 #endif
2352 #endif
2354 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
2356 int len;
2357 char *ret;
2358 va_list ap2;
2359 char c;
2361 /* this call looks strange, but it makes it work on older solaris boxes */
2362 va_copy(ap2, ap);
2363 len = vsnprintf(&c, 1, fmt, ap2);
2364 va_end(ap2);
2365 if (unlikely(len < 0)) {
2366 return NULL;
2369 ret = (char *)__talloc(t, len+1);
2370 if (unlikely(!ret)) return NULL;
2372 va_copy(ap2, ap);
2373 vsnprintf(ret, len+1, fmt, ap2);
2374 va_end(ap2);
2376 _talloc_set_name_const(ret, ret);
2377 return ret;
2382 Perform string formatting, and return a pointer to newly allocated
2383 memory holding the result, inside a memory pool.
2385 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
2387 va_list ap;
2388 char *ret;
2390 va_start(ap, fmt);
2391 ret = talloc_vasprintf(t, fmt, ap);
2392 va_end(ap);
2393 return ret;
2396 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2397 const char *fmt, va_list ap)
2398 PRINTF_ATTRIBUTE(3,0);
2400 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2401 const char *fmt, va_list ap)
2403 ssize_t alen;
2404 va_list ap2;
2405 char c;
2407 va_copy(ap2, ap);
2408 alen = vsnprintf(&c, 1, fmt, ap2);
2409 va_end(ap2);
2411 if (alen <= 0) {
2412 /* Either the vsnprintf failed or the format resulted in
2413 * no characters being formatted. In the former case, we
2414 * ought to return NULL, in the latter we ought to return
2415 * the original string. Most current callers of this
2416 * function expect it to never return NULL.
2418 return s;
2421 s = talloc_realloc(NULL, s, char, slen + alen + 1);
2422 if (!s) return NULL;
2424 va_copy(ap2, ap);
2425 vsnprintf(s + slen, alen + 1, fmt, ap2);
2426 va_end(ap2);
2428 _talloc_set_name_const(s, s);
2429 return s;
2433 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2434 * and return @p s, which may have moved. Good for gradually
2435 * accumulating output into a string buffer. Appends at the end
2436 * of the string.
2438 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2440 if (unlikely(!s)) {
2441 return talloc_vasprintf(NULL, fmt, ap);
2444 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2448 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2449 * and return @p s, which may have moved. Always appends at the
2450 * end of the talloc'ed buffer, not the end of the string.
2452 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2454 size_t slen;
2456 if (unlikely(!s)) {
2457 return talloc_vasprintf(NULL, fmt, ap);
2460 slen = talloc_get_size(s);
2461 if (likely(slen > 0)) {
2462 slen--;
2465 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
2469 Realloc @p s to append the formatted result of @p fmt and return @p
2470 s, which may have moved. Good for gradually accumulating output
2471 into a string buffer.
2473 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2475 va_list ap;
2477 va_start(ap, fmt);
2478 s = talloc_vasprintf_append(s, fmt, ap);
2479 va_end(ap);
2480 return s;
2484 Realloc @p s to append the formatted result of @p fmt and return @p
2485 s, which may have moved. Good for gradually accumulating output
2486 into a buffer.
2488 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2490 va_list ap;
2492 va_start(ap, fmt);
2493 s = talloc_vasprintf_append_buffer(s, fmt, ap);
2494 va_end(ap);
2495 return s;
2499 alloc an array, checking for integer overflow in the array size
2501 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2503 if (count >= MAX_TALLOC_SIZE/el_size) {
2504 return NULL;
2506 return _talloc_named_const(ctx, el_size * count, name);
2510 alloc an zero array, checking for integer overflow in the array size
2512 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2514 if (count >= MAX_TALLOC_SIZE/el_size) {
2515 return NULL;
2517 return _talloc_zero(ctx, el_size * count, name);
2521 realloc an array, checking for integer overflow in the array size
2523 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2525 if (count >= MAX_TALLOC_SIZE/el_size) {
2526 return NULL;
2528 return _talloc_realloc(ctx, ptr, el_size * count, name);
2532 a function version of talloc_realloc(), so it can be passed as a function pointer
2533 to libraries that want a realloc function (a realloc function encapsulates
2534 all the basic capabilities of an allocation library, which is why this is useful)
2536 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2538 return _talloc_realloc(context, ptr, size, NULL);
2542 static int talloc_autofree_destructor(void *ptr)
2544 autofree_context = NULL;
2545 return 0;
2548 static void talloc_autofree(void)
2550 talloc_free(autofree_context);
2554 return a context which will be auto-freed on exit
2555 this is useful for reducing the noise in leak reports
2557 _PUBLIC_ void *talloc_autofree_context(void)
2559 if (autofree_context == NULL) {
2560 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2561 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2562 atexit(talloc_autofree);
2564 return autofree_context;
2567 _PUBLIC_ size_t talloc_get_size(const void *context)
2569 struct talloc_chunk *tc;
2571 if (context == NULL) {
2572 context = null_context;
2574 if (context == NULL) {
2575 return 0;
2578 tc = talloc_chunk_from_ptr(context);
2580 return tc->size;
2584 find a parent of this context that has the given name, if any
2586 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2588 struct talloc_chunk *tc;
2590 if (context == NULL) {
2591 return NULL;
2594 tc = talloc_chunk_from_ptr(context);
2595 while (tc) {
2596 if (tc->name && strcmp(tc->name, name) == 0) {
2597 return TC_PTR_FROM_CHUNK(tc);
2599 while (tc && tc->prev) tc = tc->prev;
2600 if (tc) {
2601 tc = tc->parent;
2604 return NULL;
2608 show the parentage of a context
2610 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2612 struct talloc_chunk *tc;
2614 if (context == NULL) {
2615 fprintf(file, "talloc no parents for NULL\n");
2616 return;
2619 tc = talloc_chunk_from_ptr(context);
2620 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
2621 while (tc) {
2622 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2623 while (tc && tc->prev) tc = tc->prev;
2624 if (tc) {
2625 tc = tc->parent;
2628 fflush(file);
2632 return 1 if ptr is a parent of context
2634 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2636 struct talloc_chunk *tc;
2638 if (context == NULL) {
2639 return 0;
2642 tc = talloc_chunk_from_ptr(context);
2643 while (tc && depth > 0) {
2644 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2645 while (tc && tc->prev) tc = tc->prev;
2646 if (tc) {
2647 tc = tc->parent;
2648 depth--;
2651 return 0;
2655 return 1 if ptr is a parent of context
2657 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2659 return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2663 return the total size of memory used by this context and all children
2665 static size_t _talloc_total_limit_size(const void *ptr,
2666 struct talloc_memlimit *old_limit,
2667 struct talloc_memlimit *new_limit)
2669 return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT,
2670 old_limit, new_limit);
2673 static bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
2675 struct talloc_memlimit *l;
2677 for (l = limit; l != NULL; l = l->upper) {
2678 if (l->max_size != 0 &&
2679 ((l->max_size <= l->cur_size) ||
2680 (l->max_size - l->cur_size < size))) {
2681 return false;
2685 return true;
2689 Update memory limits when freeing a talloc_chunk.
2691 static void talloc_memlimit_update_on_free(struct talloc_chunk *tc)
2693 size_t limit_shrink_size;
2695 if (!tc->limit) {
2696 return;
2700 * Pool entries don't count. Only the pools
2701 * themselves are counted as part of the memory
2702 * limits. Note that this also takes care of
2703 * nested pools which have both flags
2704 * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set.
2706 if (tc->flags & TALLOC_FLAG_POOLMEM) {
2707 return;
2711 * If we are part of a memory limited context hierarchy
2712 * we need to subtract the memory used from the counters
2715 limit_shrink_size = tc->size+TC_HDR_SIZE;
2718 * If we're deallocating a pool, take into
2719 * account the prefix size added for the pool.
2722 if (tc->flags & TALLOC_FLAG_POOL) {
2723 limit_shrink_size += TP_HDR_SIZE;
2726 talloc_memlimit_shrink(tc->limit, limit_shrink_size);
2728 if (tc->limit->parent == tc) {
2729 free(tc->limit);
2732 tc->limit = NULL;
2736 Increase memory limit accounting after a malloc/realloc.
2738 static void talloc_memlimit_grow(struct talloc_memlimit *limit,
2739 size_t size)
2741 struct talloc_memlimit *l;
2743 for (l = limit; l != NULL; l = l->upper) {
2744 size_t new_cur_size = l->cur_size + size;
2745 if (new_cur_size < l->cur_size) {
2746 talloc_abort("logic error in talloc_memlimit_grow\n");
2747 return;
2749 l->cur_size = new_cur_size;
2754 Decrease memory limit accounting after a free/realloc.
2756 static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
2757 size_t size)
2759 struct talloc_memlimit *l;
2761 for (l = limit; l != NULL; l = l->upper) {
2762 if (l->cur_size < size) {
2763 talloc_abort("logic error in talloc_memlimit_shrink\n");
2764 return;
2766 l->cur_size = l->cur_size - size;
2770 _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
2772 struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
2773 struct talloc_memlimit *orig_limit;
2774 struct talloc_memlimit *limit = NULL;
2776 if (tc->limit && tc->limit->parent == tc) {
2777 tc->limit->max_size = max_size;
2778 return 0;
2780 orig_limit = tc->limit;
2782 limit = malloc(sizeof(struct talloc_memlimit));
2783 if (limit == NULL) {
2784 return 1;
2786 limit->parent = tc;
2787 limit->max_size = max_size;
2788 limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit);
2790 if (orig_limit) {
2791 limit->upper = orig_limit;
2792 } else {
2793 limit->upper = NULL;
2796 return 0;