s4:libcli/smb2: add smb2_session_channel()
[Samba.git] / lib / talloc / talloc.c
blobfa56ea5678061a21c7e38f25ed5463921d79e761
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 inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
239 static inline void talloc_memlimit_grow(struct talloc_memlimit *limit,
240 size_t size);
241 static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit,
242 size_t size);
243 static inline void talloc_memlimit_update_on_free(struct talloc_chunk *tc);
245 static inline void _talloc_set_name_const(const void *ptr, const char *name);
247 typedef int (*talloc_destructor_t)(void *);
249 struct talloc_pool_hdr;
251 struct talloc_chunk {
252 struct talloc_chunk *next, *prev;
253 struct talloc_chunk *parent, *child;
254 struct talloc_reference_handle *refs;
255 talloc_destructor_t destructor;
256 const char *name;
257 size_t size;
258 unsigned flags;
261 * limit semantics:
262 * if 'limit' is set it means all *new* children of the context will
263 * be limited to a total aggregate size ox max_size for memory
264 * allocations.
265 * cur_size is used to keep track of the current use
267 struct talloc_memlimit *limit;
270 * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
271 * is a pointer to the struct talloc_chunk of the pool that it was
272 * allocated from. This way children can quickly find the pool to chew
273 * from.
275 struct talloc_pool_hdr *pool;
278 /* 16 byte alignment seems to keep everyone happy */
279 #define TC_ALIGN16(s) (((s)+15)&~15)
280 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
281 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
283 _PUBLIC_ int talloc_version_major(void)
285 return TALLOC_VERSION_MAJOR;
288 _PUBLIC_ int talloc_version_minor(void)
290 return TALLOC_VERSION_MINOR;
293 static void (*talloc_log_fn)(const char *message);
295 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
297 talloc_log_fn = log_fn;
300 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
301 static void talloc_log(const char *fmt, ...)
303 va_list ap;
304 char *message;
306 if (!talloc_log_fn) {
307 return;
310 va_start(ap, fmt);
311 message = talloc_vasprintf(NULL, fmt, ap);
312 va_end(ap);
314 talloc_log_fn(message);
315 talloc_free(message);
318 static void talloc_log_stderr(const char *message)
320 fprintf(stderr, "%s", message);
323 _PUBLIC_ void talloc_set_log_stderr(void)
325 talloc_set_log_fn(talloc_log_stderr);
328 static void (*talloc_abort_fn)(const char *reason);
330 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
332 talloc_abort_fn = abort_fn;
335 static void talloc_abort(const char *reason)
337 talloc_log("%s\n", reason);
339 if (!talloc_abort_fn) {
340 TALLOC_ABORT(reason);
343 talloc_abort_fn(reason);
346 static void talloc_abort_magic(unsigned magic)
348 unsigned striped = magic - TALLOC_MAGIC_BASE;
349 unsigned major = (striped & 0xFFFFF000) >> 12;
350 unsigned minor = (striped & 0x00000FF0) >> 4;
351 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
352 magic, major, minor,
353 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
354 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
357 static void talloc_abort_access_after_free(void)
359 talloc_abort("Bad talloc magic value - access after free");
362 static void talloc_abort_unknown_value(void)
364 talloc_abort("Bad talloc magic value - unknown value");
367 /* panic if we get a bad magic value */
368 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
370 const char *pp = (const char *)ptr;
371 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
372 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
373 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
374 talloc_abort_magic(tc->flags & (~0xF));
375 return NULL;
378 if (tc->flags & TALLOC_FLAG_FREE) {
379 talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
380 talloc_abort_access_after_free();
381 return NULL;
382 } else {
383 talloc_abort_unknown_value();
384 return NULL;
387 return tc;
390 /* hook into the front of the list */
391 #define _TLIST_ADD(list, p) \
392 do { \
393 if (!(list)) { \
394 (list) = (p); \
395 (p)->next = (p)->prev = NULL; \
396 } else { \
397 (list)->prev = (p); \
398 (p)->next = (list); \
399 (p)->prev = NULL; \
400 (list) = (p); \
402 } while (0)
404 /* remove an element from a list - element doesn't have to be in list. */
405 #define _TLIST_REMOVE(list, p) \
406 do { \
407 if ((p) == (list)) { \
408 (list) = (p)->next; \
409 if (list) (list)->prev = NULL; \
410 } else { \
411 if ((p)->prev) (p)->prev->next = (p)->next; \
412 if ((p)->next) (p)->next->prev = (p)->prev; \
414 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
415 } while (0)
419 return the parent chunk of a pointer
421 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
423 struct talloc_chunk *tc;
425 if (unlikely(ptr == NULL)) {
426 return NULL;
429 tc = talloc_chunk_from_ptr(ptr);
430 while (tc->prev) tc=tc->prev;
432 return tc->parent;
435 _PUBLIC_ void *talloc_parent(const void *ptr)
437 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
438 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
442 find parents name
444 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
446 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
447 return tc? tc->name : NULL;
451 A pool carries an in-pool object count count in the first 16 bytes.
452 bytes. This is done to support talloc_steal() to a parent outside of the
453 pool. The count includes the pool itself, so a talloc_free() on a pool will
454 only destroy the pool if the count has dropped to zero. A talloc_free() of a
455 pool member will reduce the count, and eventually also call free(3) on the
456 pool memory.
458 The object count is not put into "struct talloc_chunk" because it is only
459 relevant for talloc pools and the alignment to 16 bytes would increase the
460 memory footprint of each talloc chunk by those 16 bytes.
463 struct talloc_pool_hdr {
464 void *end;
465 unsigned int object_count;
466 size_t poolsize;
469 #define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr))
471 static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c)
473 return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE);
476 static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h)
478 return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE);
481 static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr)
483 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
484 return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize;
487 static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr)
489 return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end;
492 /* If tc is inside a pool, this gives the next neighbour. */
493 static inline void *tc_next_chunk(struct talloc_chunk *tc)
495 return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
498 static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr)
500 struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
501 return tc_next_chunk(tc);
504 /* Mark the whole remaining pool as not accessable */
505 static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr)
507 size_t flen = tc_pool_space_left(pool_hdr);
509 if (unlikely(talloc_fill.enabled)) {
510 memset(pool_hdr->end, talloc_fill.fill_value, flen);
513 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
514 VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen);
515 #endif
519 Allocate from a pool
522 static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
523 size_t size, size_t prefix_len)
525 struct talloc_pool_hdr *pool_hdr = NULL;
526 size_t space_left;
527 struct talloc_chunk *result;
528 size_t chunk_size;
530 if (parent == NULL) {
531 return NULL;
534 if (parent->flags & TALLOC_FLAG_POOL) {
535 pool_hdr = talloc_pool_from_chunk(parent);
537 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
538 pool_hdr = parent->pool;
541 if (pool_hdr == NULL) {
542 return NULL;
545 space_left = tc_pool_space_left(pool_hdr);
548 * Align size to 16 bytes
550 chunk_size = TC_ALIGN16(size + prefix_len);
552 if (space_left < chunk_size) {
553 return NULL;
556 result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len);
558 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
559 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size);
560 #endif
562 pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size);
564 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
565 result->pool = pool_hdr;
567 pool_hdr->object_count++;
569 return result;
573 Allocate a bit of memory as a child of an existing pointer
575 static inline void *__talloc_with_prefix(const void *context, size_t size,
576 size_t prefix_len)
578 struct talloc_chunk *tc = NULL;
579 struct talloc_memlimit *limit = NULL;
580 size_t total_len = TC_HDR_SIZE + size + prefix_len;
582 if (unlikely(context == NULL)) {
583 context = null_context;
586 if (unlikely(size >= MAX_TALLOC_SIZE)) {
587 return NULL;
590 if (unlikely(total_len < TC_HDR_SIZE)) {
591 return NULL;
594 if (context != NULL) {
595 struct talloc_chunk *ptc = talloc_chunk_from_ptr(context);
597 if (ptc->limit != NULL) {
598 limit = ptc->limit;
601 tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len);
604 if (tc == NULL) {
605 char *ptr;
608 * Only do the memlimit check/update on actual allocation.
610 if (!talloc_memlimit_check(limit, total_len)) {
611 errno = ENOMEM;
612 return NULL;
615 ptr = malloc(total_len);
616 if (unlikely(ptr == NULL)) {
617 return NULL;
619 tc = (struct talloc_chunk *)(ptr + prefix_len);
620 tc->flags = TALLOC_MAGIC;
621 tc->pool = NULL;
623 talloc_memlimit_grow(limit, total_len);
626 tc->limit = limit;
627 tc->size = size;
628 tc->destructor = NULL;
629 tc->child = NULL;
630 tc->name = NULL;
631 tc->refs = NULL;
633 if (likely(context)) {
634 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
636 if (parent->child) {
637 parent->child->parent = NULL;
638 tc->next = parent->child;
639 tc->next->prev = tc;
640 } else {
641 tc->next = NULL;
643 tc->parent = parent;
644 tc->prev = NULL;
645 parent->child = tc;
646 } else {
647 tc->next = tc->prev = tc->parent = NULL;
650 return TC_PTR_FROM_CHUNK(tc);
653 static inline void *__talloc(const void *context, size_t size)
655 return __talloc_with_prefix(context, size, 0);
659 * Create a talloc pool
662 static inline void *_talloc_pool(const void *context, size_t size)
664 struct talloc_chunk *tc;
665 struct talloc_pool_hdr *pool_hdr;
666 void *result;
668 result = __talloc_with_prefix(context, size, TP_HDR_SIZE);
670 if (unlikely(result == NULL)) {
671 return NULL;
674 tc = talloc_chunk_from_ptr(result);
675 pool_hdr = talloc_pool_from_chunk(tc);
677 tc->flags |= TALLOC_FLAG_POOL;
678 tc->size = 0;
680 pool_hdr->object_count = 1;
681 pool_hdr->end = result;
682 pool_hdr->poolsize = size;
684 tc_invalidate_pool(pool_hdr);
686 return result;
689 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
691 return _talloc_pool(context, size);
695 * Create a talloc pool correctly sized for a basic size plus
696 * a number of subobjects whose total size is given. Essentially
697 * a custom allocator for talloc to reduce fragmentation.
700 _PUBLIC_ void *_talloc_pooled_object(const void *ctx,
701 size_t type_size,
702 const char *type_name,
703 unsigned num_subobjects,
704 size_t total_subobjects_size)
706 size_t poolsize, subobjects_slack, tmp;
707 struct talloc_chunk *tc;
708 struct talloc_pool_hdr *pool_hdr;
709 void *ret;
711 poolsize = type_size + total_subobjects_size;
713 if ((poolsize < type_size) || (poolsize < total_subobjects_size)) {
714 goto overflow;
717 if (num_subobjects == UINT_MAX) {
718 goto overflow;
720 num_subobjects += 1; /* the object body itself */
723 * Alignment can increase the pool size by at most 15 bytes per object
724 * plus alignment for the object itself
726 subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects;
727 if (subobjects_slack < num_subobjects) {
728 goto overflow;
731 tmp = poolsize + subobjects_slack;
732 if ((tmp < poolsize) || (tmp < subobjects_slack)) {
733 goto overflow;
735 poolsize = tmp;
737 ret = _talloc_pool(ctx, poolsize);
738 if (ret == NULL) {
739 return NULL;
742 tc = talloc_chunk_from_ptr(ret);
743 tc->size = type_size;
745 pool_hdr = talloc_pool_from_chunk(tc);
747 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
748 VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size);
749 #endif
751 pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size));
753 _talloc_set_name_const(ret, type_name);
754 return ret;
756 overflow:
757 return NULL;
761 setup a destructor to be called on free of a pointer
762 the destructor should return 0 on success, or -1 on failure.
763 if the destructor fails then the free is failed, and the memory can
764 be continued to be used
766 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
768 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
769 tc->destructor = destructor;
773 increase the reference count on a piece of memory.
775 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
777 if (unlikely(!talloc_reference(null_context, ptr))) {
778 return -1;
780 return 0;
784 helper for talloc_reference()
786 this is referenced by a function pointer and should not be inline
788 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
790 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
791 _TLIST_REMOVE(ptr_tc->refs, handle);
792 return 0;
796 more efficient way to add a name to a pointer - the name must point to a
797 true string constant
799 static inline void _talloc_set_name_const(const void *ptr, const char *name)
801 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
802 tc->name = name;
806 internal talloc_named_const()
808 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
810 void *ptr;
812 ptr = __talloc(context, size);
813 if (unlikely(ptr == NULL)) {
814 return NULL;
817 _talloc_set_name_const(ptr, name);
819 return ptr;
823 make a secondary reference to a pointer, hanging off the given context.
824 the pointer remains valid until both the original caller and this given
825 context are freed.
827 the major use for this is when two different structures need to reference the
828 same underlying data, and you want to be able to free the two instances separately,
829 and in either order
831 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
833 struct talloc_chunk *tc;
834 struct talloc_reference_handle *handle;
835 if (unlikely(ptr == NULL)) return NULL;
837 tc = talloc_chunk_from_ptr(ptr);
838 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
839 sizeof(struct talloc_reference_handle),
840 TALLOC_MAGIC_REFERENCE);
841 if (unlikely(handle == NULL)) return NULL;
843 /* note that we hang the destructor off the handle, not the
844 main context as that allows the caller to still setup their
845 own destructor on the context if they want to */
846 talloc_set_destructor(handle, talloc_reference_destructor);
847 handle->ptr = discard_const_p(void, ptr);
848 handle->location = location;
849 _TLIST_ADD(tc->refs, handle);
850 return handle->ptr;
853 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
855 static inline void _talloc_free_poolmem(struct talloc_chunk *tc,
856 const char *location)
858 struct talloc_pool_hdr *pool;
859 struct talloc_chunk *pool_tc;
860 void *next_tc;
862 pool = tc->pool;
863 pool_tc = talloc_chunk_from_pool(pool);
864 next_tc = tc_next_chunk(tc);
866 tc->flags |= TALLOC_FLAG_FREE;
868 /* we mark the freed memory with where we called the free
869 * from. This means on a double free error we can report where
870 * the first free came from
872 tc->name = location;
874 TC_INVALIDATE_FULL_CHUNK(tc);
876 if (unlikely(pool->object_count == 0)) {
877 talloc_abort("Pool object count zero!");
878 return;
881 pool->object_count--;
883 if (unlikely(pool->object_count == 1
884 && !(pool_tc->flags & TALLOC_FLAG_FREE))) {
886 * if there is just one object left in the pool
887 * and pool->flags does not have TALLOC_FLAG_FREE,
888 * it means this is the pool itself and
889 * the rest is available for new objects
890 * again.
892 pool->end = tc_pool_first_chunk(pool);
893 tc_invalidate_pool(pool);
894 return;
897 if (unlikely(pool->object_count == 0)) {
899 * we mark the freed memory with where we called the free
900 * from. This means on a double free error we can report where
901 * the first free came from
903 pool_tc->name = location;
905 if (pool_tc->flags & TALLOC_FLAG_POOLMEM) {
906 _talloc_free_poolmem(pool_tc, location);
907 } else {
909 * The talloc_memlimit_update_on_free()
910 * call takes into account the
911 * prefix TP_HDR_SIZE allocated before
912 * the pool talloc_chunk.
914 talloc_memlimit_update_on_free(pool_tc);
915 TC_INVALIDATE_FULL_CHUNK(pool_tc);
916 free(pool);
918 return;
921 if (pool->end == next_tc) {
923 * if pool->pool still points to end of
924 * 'tc' (which is stored in the 'next_tc' variable),
925 * we can reclaim the memory of 'tc'.
927 pool->end = tc;
928 return;
932 * Do nothing. The memory is just "wasted", waiting for the pool
933 * itself to be freed.
937 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
938 void *ptr,
939 const char *location);
942 internal talloc_free call
944 static inline int _talloc_free_internal(void *ptr, const char *location)
946 struct talloc_chunk *tc;
947 void *ptr_to_free;
949 if (unlikely(ptr == NULL)) {
950 return -1;
953 /* possibly initialised the talloc fill value */
954 if (unlikely(!talloc_fill.initialised)) {
955 const char *fill = getenv(TALLOC_FILL_ENV);
956 if (fill != NULL) {
957 talloc_fill.enabled = true;
958 talloc_fill.fill_value = strtoul(fill, NULL, 0);
960 talloc_fill.initialised = true;
963 tc = talloc_chunk_from_ptr(ptr);
965 if (unlikely(tc->refs)) {
966 int is_child;
967 /* check if this is a reference from a child or
968 * grandchild back to it's parent or grandparent
970 * in that case we need to remove the reference and
971 * call another instance of talloc_free() on the current
972 * pointer.
974 is_child = talloc_is_parent(tc->refs, ptr);
975 _talloc_free_internal(tc->refs, location);
976 if (is_child) {
977 return _talloc_free_internal(ptr, location);
979 return -1;
982 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
983 /* we have a free loop - stop looping */
984 return 0;
987 if (unlikely(tc->destructor)) {
988 talloc_destructor_t d = tc->destructor;
989 if (d == (talloc_destructor_t)-1) {
990 return -1;
992 tc->destructor = (talloc_destructor_t)-1;
993 if (d(ptr) == -1) {
994 tc->destructor = d;
995 return -1;
997 tc->destructor = NULL;
1000 if (tc->parent) {
1001 _TLIST_REMOVE(tc->parent->child, tc);
1002 if (tc->parent->child) {
1003 tc->parent->child->parent = tc->parent;
1005 } else {
1006 if (tc->prev) tc->prev->next = tc->next;
1007 if (tc->next) tc->next->prev = tc->prev;
1008 tc->prev = tc->next = NULL;
1011 tc->flags |= TALLOC_FLAG_LOOP;
1013 _talloc_free_children_internal(tc, ptr, location);
1015 tc->flags |= TALLOC_FLAG_FREE;
1017 /* we mark the freed memory with where we called the free
1018 * from. This means on a double free error we can report where
1019 * the first free came from
1021 tc->name = location;
1023 if (tc->flags & TALLOC_FLAG_POOL) {
1024 struct talloc_pool_hdr *pool;
1026 pool = talloc_pool_from_chunk(tc);
1028 if (unlikely(pool->object_count == 0)) {
1029 talloc_abort("Pool object count zero!");
1030 return 0;
1033 pool->object_count--;
1035 if (likely(pool->object_count != 0)) {
1036 return 0;
1040 * With object_count==0, a pool becomes a normal piece of
1041 * memory to free. If it's allocated inside a pool, it needs
1042 * to be freed as poolmem, else it needs to be just freed.
1044 ptr_to_free = pool;
1045 } else {
1046 ptr_to_free = tc;
1049 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1050 _talloc_free_poolmem(tc, location);
1051 return 0;
1054 talloc_memlimit_update_on_free(tc);
1056 TC_INVALIDATE_FULL_CHUNK(tc);
1057 free(ptr_to_free);
1058 return 0;
1061 static size_t _talloc_total_limit_size(const void *ptr,
1062 struct talloc_memlimit *old_limit,
1063 struct talloc_memlimit *new_limit);
1066 move a lump of memory from one talloc context to another return the
1067 ptr on success, or NULL if it could not be transferred.
1068 passing NULL as ptr will always return NULL with no side effects.
1070 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
1072 struct talloc_chunk *tc, *new_tc;
1073 size_t ctx_size = 0;
1075 if (unlikely(!ptr)) {
1076 return NULL;
1079 if (unlikely(new_ctx == NULL)) {
1080 new_ctx = null_context;
1083 tc = talloc_chunk_from_ptr(ptr);
1085 if (tc->limit != NULL) {
1087 ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
1089 /* Decrement the memory limit from the source .. */
1090 talloc_memlimit_shrink(tc->limit->upper, ctx_size);
1092 if (tc->limit->parent == tc) {
1093 tc->limit->upper = NULL;
1094 } else {
1095 tc->limit = NULL;
1099 if (unlikely(new_ctx == NULL)) {
1100 if (tc->parent) {
1101 _TLIST_REMOVE(tc->parent->child, tc);
1102 if (tc->parent->child) {
1103 tc->parent->child->parent = tc->parent;
1105 } else {
1106 if (tc->prev) tc->prev->next = tc->next;
1107 if (tc->next) tc->next->prev = tc->prev;
1110 tc->parent = tc->next = tc->prev = NULL;
1111 return discard_const_p(void, ptr);
1114 new_tc = talloc_chunk_from_ptr(new_ctx);
1116 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
1117 return discard_const_p(void, ptr);
1120 if (tc->parent) {
1121 _TLIST_REMOVE(tc->parent->child, tc);
1122 if (tc->parent->child) {
1123 tc->parent->child->parent = tc->parent;
1125 } else {
1126 if (tc->prev) tc->prev->next = tc->next;
1127 if (tc->next) tc->next->prev = tc->prev;
1128 tc->prev = tc->next = NULL;
1131 tc->parent = new_tc;
1132 if (new_tc->child) new_tc->child->parent = NULL;
1133 _TLIST_ADD(new_tc->child, tc);
1135 if (tc->limit || new_tc->limit) {
1136 ctx_size = _talloc_total_limit_size(ptr, tc->limit,
1137 new_tc->limit);
1138 /* .. and increment it in the destination. */
1139 if (new_tc->limit) {
1140 talloc_memlimit_grow(new_tc->limit, ctx_size);
1144 return discard_const_p(void, ptr);
1148 move a lump of memory from one talloc context to another return the
1149 ptr on success, or NULL if it could not be transferred.
1150 passing NULL as ptr will always return NULL with no side effects.
1152 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
1154 struct talloc_chunk *tc;
1156 if (unlikely(ptr == NULL)) {
1157 return NULL;
1160 tc = talloc_chunk_from_ptr(ptr);
1162 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
1163 struct talloc_reference_handle *h;
1165 talloc_log("WARNING: talloc_steal with references at %s\n",
1166 location);
1168 for (h=tc->refs; h; h=h->next) {
1169 talloc_log("\treference at %s\n",
1170 h->location);
1174 #if 0
1175 /* this test is probably too expensive to have on in the
1176 normal build, but it useful for debugging */
1177 if (talloc_is_parent(new_ctx, ptr)) {
1178 talloc_log("WARNING: stealing into talloc child at %s\n", location);
1180 #endif
1182 return _talloc_steal_internal(new_ctx, ptr);
1186 this is like a talloc_steal(), but you must supply the old
1187 parent. This resolves the ambiguity in a talloc_steal() which is
1188 called on a context that has more than one parent (via references)
1190 The old parent can be either a reference or a parent
1192 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
1194 struct talloc_chunk *tc;
1195 struct talloc_reference_handle *h;
1197 if (unlikely(ptr == NULL)) {
1198 return NULL;
1201 if (old_parent == talloc_parent(ptr)) {
1202 return _talloc_steal_internal(new_parent, ptr);
1205 tc = talloc_chunk_from_ptr(ptr);
1206 for (h=tc->refs;h;h=h->next) {
1207 if (talloc_parent(h) == old_parent) {
1208 if (_talloc_steal_internal(new_parent, h) != h) {
1209 return NULL;
1211 return discard_const_p(void, ptr);
1215 /* it wasn't a parent */
1216 return NULL;
1220 remove a secondary reference to a pointer. This undo's what
1221 talloc_reference() has done. The context and pointer arguments
1222 must match those given to a talloc_reference()
1224 static inline int talloc_unreference(const void *context, const void *ptr)
1226 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1227 struct talloc_reference_handle *h;
1229 if (unlikely(context == NULL)) {
1230 context = null_context;
1233 for (h=tc->refs;h;h=h->next) {
1234 struct talloc_chunk *p = talloc_parent_chunk(h);
1235 if (p == NULL) {
1236 if (context == NULL) break;
1237 } else if (TC_PTR_FROM_CHUNK(p) == context) {
1238 break;
1241 if (h == NULL) {
1242 return -1;
1245 return _talloc_free_internal(h, __location__);
1249 remove a specific parent context from a pointer. This is a more
1250 controlled variant of talloc_free()
1252 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
1254 struct talloc_chunk *tc_p, *new_p, *tc_c;
1255 void *new_parent;
1257 if (ptr == NULL) {
1258 return -1;
1261 if (context == NULL) {
1262 context = null_context;
1265 if (talloc_unreference(context, ptr) == 0) {
1266 return 0;
1269 if (context != NULL) {
1270 tc_c = talloc_chunk_from_ptr(context);
1271 } else {
1272 tc_c = NULL;
1274 if (tc_c != talloc_parent_chunk(ptr)) {
1275 return -1;
1278 tc_p = talloc_chunk_from_ptr(ptr);
1280 if (tc_p->refs == NULL) {
1281 return _talloc_free_internal(ptr, __location__);
1284 new_p = talloc_parent_chunk(tc_p->refs);
1285 if (new_p) {
1286 new_parent = TC_PTR_FROM_CHUNK(new_p);
1287 } else {
1288 new_parent = NULL;
1291 if (talloc_unreference(new_parent, ptr) != 0) {
1292 return -1;
1295 _talloc_steal_internal(new_parent, ptr);
1297 return 0;
1301 add a name to an existing pointer - va_list version
1303 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1305 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
1307 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1308 tc->name = talloc_vasprintf(ptr, fmt, ap);
1309 if (likely(tc->name)) {
1310 _talloc_set_name_const(tc->name, ".name");
1312 return tc->name;
1316 add a name to an existing pointer
1318 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1320 const char *name;
1321 va_list ap;
1322 va_start(ap, fmt);
1323 name = talloc_set_name_v(ptr, fmt, ap);
1324 va_end(ap);
1325 return name;
1330 create a named talloc pointer. Any talloc pointer can be named, and
1331 talloc_named() operates just like talloc() except that it allows you
1332 to name the pointer.
1334 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1336 va_list ap;
1337 void *ptr;
1338 const char *name;
1340 ptr = __talloc(context, size);
1341 if (unlikely(ptr == NULL)) return NULL;
1343 va_start(ap, fmt);
1344 name = talloc_set_name_v(ptr, fmt, ap);
1345 va_end(ap);
1347 if (unlikely(name == NULL)) {
1348 _talloc_free_internal(ptr, __location__);
1349 return NULL;
1352 return ptr;
1356 return the name of a talloc ptr, or "UNNAMED"
1358 static inline const char *__talloc_get_name(const void *ptr)
1360 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1361 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1362 return ".reference";
1364 if (likely(tc->name)) {
1365 return tc->name;
1367 return "UNNAMED";
1370 _PUBLIC_ const char *talloc_get_name(const void *ptr)
1372 return __talloc_get_name(ptr);
1376 check if a pointer has the given name. If it does, return the pointer,
1377 otherwise return NULL
1379 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1381 const char *pname;
1382 if (unlikely(ptr == NULL)) return NULL;
1383 pname = __talloc_get_name(ptr);
1384 if (likely(pname == name || strcmp(pname, name) == 0)) {
1385 return discard_const_p(void, ptr);
1387 return NULL;
1390 static void talloc_abort_type_mismatch(const char *location,
1391 const char *name,
1392 const char *expected)
1394 const char *reason;
1396 reason = talloc_asprintf(NULL,
1397 "%s: Type mismatch: name[%s] expected[%s]",
1398 location,
1399 name?name:"NULL",
1400 expected);
1401 if (!reason) {
1402 reason = "Type mismatch";
1405 talloc_abort(reason);
1408 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1410 const char *pname;
1412 if (unlikely(ptr == NULL)) {
1413 talloc_abort_type_mismatch(location, NULL, name);
1414 return NULL;
1417 pname = __talloc_get_name(ptr);
1418 if (likely(pname == name || strcmp(pname, name) == 0)) {
1419 return discard_const_p(void, ptr);
1422 talloc_abort_type_mismatch(location, pname, name);
1423 return NULL;
1427 this is for compatibility with older versions of talloc
1429 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1431 va_list ap;
1432 void *ptr;
1433 const char *name;
1435 ptr = __talloc(NULL, 0);
1436 if (unlikely(ptr == NULL)) return NULL;
1438 va_start(ap, fmt);
1439 name = talloc_set_name_v(ptr, fmt, ap);
1440 va_end(ap);
1442 if (unlikely(name == NULL)) {
1443 _talloc_free_internal(ptr, __location__);
1444 return NULL;
1447 return ptr;
1450 static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
1451 void *ptr,
1452 const char *location)
1454 while (tc->child) {
1455 /* we need to work out who will own an abandoned child
1456 if it cannot be freed. In priority order, the first
1457 choice is owner of any remaining reference to this
1458 pointer, the second choice is our parent, and the
1459 final choice is the null context. */
1460 void *child = TC_PTR_FROM_CHUNK(tc->child);
1461 const void *new_parent = null_context;
1462 if (unlikely(tc->child->refs)) {
1463 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1464 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1466 if (unlikely(_talloc_free_internal(child, location) == -1)) {
1467 if (new_parent == null_context) {
1468 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1469 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1471 _talloc_steal_internal(new_parent, child);
1477 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1478 should probably not be used in new code. It's in here to keep the talloc
1479 code consistent across Samba 3 and 4.
1481 _PUBLIC_ void talloc_free_children(void *ptr)
1483 struct talloc_chunk *tc_name = NULL;
1484 struct talloc_chunk *tc;
1486 if (unlikely(ptr == NULL)) {
1487 return;
1490 tc = talloc_chunk_from_ptr(ptr);
1492 /* we do not want to free the context name if it is a child .. */
1493 if (likely(tc->child)) {
1494 for (tc_name = tc->child; tc_name; tc_name = tc_name->next) {
1495 if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break;
1497 if (tc_name) {
1498 _TLIST_REMOVE(tc->child, tc_name);
1499 if (tc->child) {
1500 tc->child->parent = tc;
1505 _talloc_free_children_internal(tc, ptr, __location__);
1507 /* .. so we put it back after all other children have been freed */
1508 if (tc_name) {
1509 if (tc->child) {
1510 tc->child->parent = NULL;
1512 tc_name->parent = tc;
1513 _TLIST_ADD(tc->child, tc_name);
1518 Allocate a bit of memory as a child of an existing pointer
1520 _PUBLIC_ void *_talloc(const void *context, size_t size)
1522 return __talloc(context, size);
1526 externally callable talloc_set_name_const()
1528 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1530 _talloc_set_name_const(ptr, name);
1534 create a named talloc pointer. Any talloc pointer can be named, and
1535 talloc_named() operates just like talloc() except that it allows you
1536 to name the pointer.
1538 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1540 return _talloc_named_const(context, size, name);
1544 free a talloc pointer. This also frees all child pointers of this
1545 pointer recursively
1547 return 0 if the memory is actually freed, otherwise -1. The memory
1548 will not be freed if the ref_count is > 1 or the destructor (if
1549 any) returns non-zero
1551 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1553 struct talloc_chunk *tc;
1555 if (unlikely(ptr == NULL)) {
1556 return -1;
1559 tc = talloc_chunk_from_ptr(ptr);
1561 if (unlikely(tc->refs != NULL)) {
1562 struct talloc_reference_handle *h;
1564 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1565 /* in this case we do know which parent should
1566 get this pointer, as there is really only
1567 one parent */
1568 return talloc_unlink(null_context, ptr);
1571 talloc_log("ERROR: talloc_free with references at %s\n",
1572 location);
1574 for (h=tc->refs; h; h=h->next) {
1575 talloc_log("\treference at %s\n",
1576 h->location);
1578 return -1;
1581 return _talloc_free_internal(ptr, location);
1587 A talloc version of realloc. The context argument is only used if
1588 ptr is NULL
1590 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1592 struct talloc_chunk *tc;
1593 void *new_ptr;
1594 bool malloced = false;
1595 struct talloc_pool_hdr *pool_hdr = NULL;
1596 size_t old_size = 0;
1597 size_t new_size = 0;
1599 /* size zero is equivalent to free() */
1600 if (unlikely(size == 0)) {
1601 talloc_unlink(context, ptr);
1602 return NULL;
1605 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1606 return NULL;
1609 /* realloc(NULL) is equivalent to malloc() */
1610 if (ptr == NULL) {
1611 return _talloc_named_const(context, size, name);
1614 tc = talloc_chunk_from_ptr(ptr);
1616 /* don't allow realloc on referenced pointers */
1617 if (unlikely(tc->refs)) {
1618 return NULL;
1621 /* don't let anybody try to realloc a talloc_pool */
1622 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1623 return NULL;
1626 if (tc->limit && (size > tc->size)) {
1627 if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
1628 errno = ENOMEM;
1629 return NULL;
1633 /* handle realloc inside a talloc_pool */
1634 if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1635 pool_hdr = tc->pool;
1638 #if (ALWAYS_REALLOC == 0)
1639 /* don't shrink if we have less than 1k to gain */
1640 if (size < tc->size && tc->limit == NULL) {
1641 if (pool_hdr) {
1642 void *next_tc = tc_next_chunk(tc);
1643 TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1644 tc->size = size;
1645 if (next_tc == pool_hdr->end) {
1646 /* note: tc->size has changed, so this works */
1647 pool_hdr->end = tc_next_chunk(tc);
1649 return ptr;
1650 } else if ((tc->size - size) < 1024) {
1652 * if we call TC_INVALIDATE_SHRINK_CHUNK() here
1653 * we would need to call TC_UNDEFINE_GROW_CHUNK()
1654 * after each realloc call, which slows down
1655 * testing a lot :-(.
1657 * That is why we only mark memory as undefined here.
1659 TC_UNDEFINE_SHRINK_CHUNK(tc, size);
1661 /* do not shrink if we have less than 1k to gain */
1662 tc->size = size;
1663 return ptr;
1665 } else if (tc->size == size) {
1667 * do not change the pointer if it is exactly
1668 * the same size.
1670 return ptr;
1672 #endif
1674 /* by resetting magic we catch users of the old memory */
1675 tc->flags |= TALLOC_FLAG_FREE;
1677 #if ALWAYS_REALLOC
1678 if (pool_hdr) {
1679 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1680 pool_hdr->object_count--;
1682 if (new_ptr == NULL) {
1683 new_ptr = malloc(TC_HDR_SIZE+size);
1684 malloced = true;
1685 new_size = size;
1688 if (new_ptr) {
1689 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1690 TC_INVALIDATE_FULL_CHUNK(tc);
1692 } else {
1693 /* We're doing malloc then free here, so record the difference. */
1694 old_size = tc->size;
1695 new_size = size;
1696 new_ptr = malloc(size + TC_HDR_SIZE);
1697 if (new_ptr) {
1698 memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1699 free(tc);
1702 #else
1703 if (pool_hdr) {
1704 struct talloc_chunk *pool_tc;
1705 void *next_tc = tc_next_chunk(tc);
1706 size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
1707 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1708 size_t space_needed;
1709 size_t space_left;
1710 unsigned int chunk_count = pool_hdr->object_count;
1712 pool_tc = talloc_chunk_from_pool(pool_hdr);
1713 if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
1714 chunk_count -= 1;
1717 if (chunk_count == 1) {
1719 * optimize for the case where 'tc' is the only
1720 * chunk in the pool.
1722 char *start = tc_pool_first_chunk(pool_hdr);
1723 space_needed = new_chunk_size;
1724 space_left = (char *)tc_pool_end(pool_hdr) - start;
1726 if (space_left >= space_needed) {
1727 size_t old_used = TC_HDR_SIZE + tc->size;
1728 size_t new_used = TC_HDR_SIZE + size;
1729 new_ptr = start;
1731 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1734 * The area from
1735 * start -> tc may have
1736 * been freed and thus been marked as
1737 * VALGRIND_MEM_NOACCESS. Set it to
1738 * VALGRIND_MEM_UNDEFINED so we can
1739 * copy into it without valgrind errors.
1740 * We can't just mark
1741 * new_ptr -> new_ptr + old_used
1742 * as this may overlap on top of tc,
1743 * (which is why we use memmove, not
1744 * memcpy below) hence the MIN.
1746 size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used);
1747 VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len);
1749 #endif
1751 memmove(new_ptr, tc, old_used);
1753 tc = (struct talloc_chunk *)new_ptr;
1754 TC_UNDEFINE_GROW_CHUNK(tc, size);
1757 * first we do not align the pool pointer
1758 * because we want to invalidate the padding
1759 * too.
1761 pool_hdr->end = new_used + (char *)new_ptr;
1762 tc_invalidate_pool(pool_hdr);
1764 /* now the aligned pointer */
1765 pool_hdr->end = new_chunk_size + (char *)new_ptr;
1766 goto got_new_ptr;
1769 next_tc = NULL;
1772 if (new_chunk_size == old_chunk_size) {
1773 TC_UNDEFINE_GROW_CHUNK(tc, size);
1774 tc->flags &= ~TALLOC_FLAG_FREE;
1775 tc->size = size;
1776 return ptr;
1779 if (next_tc == pool_hdr->end) {
1781 * optimize for the case where 'tc' is the last
1782 * chunk in the pool.
1784 space_needed = new_chunk_size - old_chunk_size;
1785 space_left = tc_pool_space_left(pool_hdr);
1787 if (space_left >= space_needed) {
1788 TC_UNDEFINE_GROW_CHUNK(tc, size);
1789 tc->flags &= ~TALLOC_FLAG_FREE;
1790 tc->size = size;
1791 pool_hdr->end = tc_next_chunk(tc);
1792 return ptr;
1796 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
1798 if (new_ptr == NULL) {
1799 new_ptr = malloc(TC_HDR_SIZE+size);
1800 malloced = true;
1801 new_size = size;
1804 if (new_ptr) {
1805 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1807 _talloc_free_poolmem(tc, __location__ "_talloc_realloc");
1810 else {
1811 /* We're doing realloc here, so record the difference. */
1812 old_size = tc->size;
1813 new_size = size;
1814 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1816 got_new_ptr:
1817 #endif
1818 if (unlikely(!new_ptr)) {
1819 tc->flags &= ~TALLOC_FLAG_FREE;
1820 return NULL;
1823 tc = (struct talloc_chunk *)new_ptr;
1824 tc->flags &= ~TALLOC_FLAG_FREE;
1825 if (malloced) {
1826 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1828 if (tc->parent) {
1829 tc->parent->child = tc;
1831 if (tc->child) {
1832 tc->child->parent = tc;
1835 if (tc->prev) {
1836 tc->prev->next = tc;
1838 if (tc->next) {
1839 tc->next->prev = tc;
1842 if (new_size > old_size) {
1843 talloc_memlimit_grow(tc->limit, new_size - old_size);
1844 } else if (new_size < old_size) {
1845 talloc_memlimit_shrink(tc->limit, old_size - new_size);
1848 tc->size = size;
1849 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1851 return TC_PTR_FROM_CHUNK(tc);
1855 a wrapper around talloc_steal() for situations where you are moving a pointer
1856 between two structures, and want the old pointer to be set to NULL
1858 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1860 const void **pptr = discard_const_p(const void *,_pptr);
1861 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1862 (*pptr) = NULL;
1863 return ret;
1866 enum talloc_mem_count_type {
1867 TOTAL_MEM_SIZE,
1868 TOTAL_MEM_BLOCKS,
1869 TOTAL_MEM_LIMIT,
1872 static inline size_t _talloc_total_mem_internal(const void *ptr,
1873 enum talloc_mem_count_type type,
1874 struct talloc_memlimit *old_limit,
1875 struct talloc_memlimit *new_limit)
1877 size_t total = 0;
1878 struct talloc_chunk *c, *tc;
1880 if (ptr == NULL) {
1881 ptr = null_context;
1883 if (ptr == NULL) {
1884 return 0;
1887 tc = talloc_chunk_from_ptr(ptr);
1889 if (old_limit || new_limit) {
1890 if (tc->limit && tc->limit->upper == old_limit) {
1891 tc->limit->upper = new_limit;
1895 /* optimize in the memlimits case */
1896 if (type == TOTAL_MEM_LIMIT &&
1897 tc->limit != NULL &&
1898 tc->limit != old_limit &&
1899 tc->limit->parent == tc) {
1900 return tc->limit->cur_size;
1903 if (tc->flags & TALLOC_FLAG_LOOP) {
1904 return 0;
1907 tc->flags |= TALLOC_FLAG_LOOP;
1909 if (old_limit || new_limit) {
1910 if (old_limit == tc->limit) {
1911 tc->limit = new_limit;
1915 switch (type) {
1916 case TOTAL_MEM_SIZE:
1917 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1918 total = tc->size;
1920 break;
1921 case TOTAL_MEM_BLOCKS:
1922 total++;
1923 break;
1924 case TOTAL_MEM_LIMIT:
1925 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1927 * Don't count memory allocated from a pool
1928 * when calculating limits. Only count the
1929 * pool itself.
1931 if (!(tc->flags & TALLOC_FLAG_POOLMEM)) {
1932 if (tc->flags & TALLOC_FLAG_POOL) {
1934 * If this is a pool, the allocated
1935 * size is in the pool header, and
1936 * remember to add in the prefix
1937 * length.
1939 struct talloc_pool_hdr *pool_hdr
1940 = talloc_pool_from_chunk(tc);
1941 total = pool_hdr->poolsize +
1942 TC_HDR_SIZE +
1943 TP_HDR_SIZE;
1944 } else {
1945 total = tc->size + TC_HDR_SIZE;
1949 break;
1951 for (c = tc->child; c; c = c->next) {
1952 total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type,
1953 old_limit, new_limit);
1956 tc->flags &= ~TALLOC_FLAG_LOOP;
1958 return total;
1962 return the total size of a talloc pool (subtree)
1964 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1966 return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL);
1970 return the total number of blocks in a talloc pool (subtree)
1972 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1974 return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL);
1978 return the number of external references to a pointer
1980 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1982 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1983 struct talloc_reference_handle *h;
1984 size_t ret = 0;
1986 for (h=tc->refs;h;h=h->next) {
1987 ret++;
1989 return ret;
1993 report on memory usage by all children of a pointer, giving a full tree view
1995 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1996 void (*callback)(const void *ptr,
1997 int depth, int max_depth,
1998 int is_ref,
1999 void *private_data),
2000 void *private_data)
2002 struct talloc_chunk *c, *tc;
2004 if (ptr == NULL) {
2005 ptr = null_context;
2007 if (ptr == NULL) return;
2009 tc = talloc_chunk_from_ptr(ptr);
2011 if (tc->flags & TALLOC_FLAG_LOOP) {
2012 return;
2015 callback(ptr, depth, max_depth, 0, private_data);
2017 if (max_depth >= 0 && depth >= max_depth) {
2018 return;
2021 tc->flags |= TALLOC_FLAG_LOOP;
2022 for (c=tc->child;c;c=c->next) {
2023 if (c->name == TALLOC_MAGIC_REFERENCE) {
2024 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
2025 callback(h->ptr, depth + 1, max_depth, 1, private_data);
2026 } else {
2027 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
2030 tc->flags &= ~TALLOC_FLAG_LOOP;
2033 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
2035 const char *name = __talloc_get_name(ptr);
2036 struct talloc_chunk *tc;
2037 FILE *f = (FILE *)_f;
2039 if (is_ref) {
2040 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
2041 return;
2044 tc = talloc_chunk_from_ptr(ptr);
2045 if (tc->limit && tc->limit->parent == tc) {
2046 fprintf(f, "%*s%-30s is a memlimit context"
2047 " (max_size = %lu bytes, cur_size = %lu bytes)\n",
2048 depth*4, "",
2049 name,
2050 (unsigned long)tc->limit->max_size,
2051 (unsigned long)tc->limit->cur_size);
2054 if (depth == 0) {
2055 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
2056 (max_depth < 0 ? "full " :""), name,
2057 (unsigned long)talloc_total_size(ptr),
2058 (unsigned long)talloc_total_blocks(ptr));
2059 return;
2062 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
2063 depth*4, "",
2064 name,
2065 (unsigned long)talloc_total_size(ptr),
2066 (unsigned long)talloc_total_blocks(ptr),
2067 (int)talloc_reference_count(ptr), ptr);
2069 #if 0
2070 fprintf(f, "content: ");
2071 if (talloc_total_size(ptr)) {
2072 int tot = talloc_total_size(ptr);
2073 int i;
2075 for (i = 0; i < tot; i++) {
2076 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
2077 fprintf(f, "%c", ((char *)ptr)[i]);
2078 } else {
2079 fprintf(f, "~%02x", ((char *)ptr)[i]);
2083 fprintf(f, "\n");
2084 #endif
2088 report on memory usage by all children of a pointer, giving a full tree view
2090 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
2092 if (f) {
2093 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
2094 fflush(f);
2099 report on memory usage by all children of a pointer, giving a full tree view
2101 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
2103 talloc_report_depth_file(ptr, 0, -1, f);
2107 report on memory usage by all children of a pointer
2109 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
2111 talloc_report_depth_file(ptr, 0, 1, f);
2115 report on any memory hanging off the null context
2117 static void talloc_report_null(void)
2119 if (talloc_total_size(null_context) != 0) {
2120 talloc_report(null_context, stderr);
2125 report on any memory hanging off the null context
2127 static void talloc_report_null_full(void)
2129 if (talloc_total_size(null_context) != 0) {
2130 talloc_report_full(null_context, stderr);
2135 enable tracking of the NULL context
2137 _PUBLIC_ void talloc_enable_null_tracking(void)
2139 if (null_context == NULL) {
2140 null_context = _talloc_named_const(NULL, 0, "null_context");
2141 if (autofree_context != NULL) {
2142 talloc_reparent(NULL, null_context, autofree_context);
2148 enable tracking of the NULL context, not moving the autofree context
2149 into the NULL context. This is needed for the talloc testsuite
2151 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
2153 if (null_context == NULL) {
2154 null_context = _talloc_named_const(NULL, 0, "null_context");
2159 disable tracking of the NULL context
2161 _PUBLIC_ void talloc_disable_null_tracking(void)
2163 if (null_context != NULL) {
2164 /* we have to move any children onto the real NULL
2165 context */
2166 struct talloc_chunk *tc, *tc2;
2167 tc = talloc_chunk_from_ptr(null_context);
2168 for (tc2 = tc->child; tc2; tc2=tc2->next) {
2169 if (tc2->parent == tc) tc2->parent = NULL;
2170 if (tc2->prev == tc) tc2->prev = NULL;
2172 for (tc2 = tc->next; tc2; tc2=tc2->next) {
2173 if (tc2->parent == tc) tc2->parent = NULL;
2174 if (tc2->prev == tc) tc2->prev = NULL;
2176 tc->child = NULL;
2177 tc->next = NULL;
2179 talloc_free(null_context);
2180 null_context = NULL;
2184 enable leak reporting on exit
2186 _PUBLIC_ void talloc_enable_leak_report(void)
2188 talloc_enable_null_tracking();
2189 atexit(talloc_report_null);
2193 enable full leak reporting on exit
2195 _PUBLIC_ void talloc_enable_leak_report_full(void)
2197 talloc_enable_null_tracking();
2198 atexit(talloc_report_null_full);
2202 talloc and zero memory.
2204 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
2206 void *p = _talloc_named_const(ctx, size, name);
2208 if (p) {
2209 memset(p, '\0', size);
2212 return p;
2216 memdup with a talloc.
2218 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
2220 void *newp = _talloc_named_const(t, size, name);
2222 if (likely(newp)) {
2223 memcpy(newp, p, size);
2226 return newp;
2229 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
2231 char *ret;
2233 ret = (char *)__talloc(t, len + 1);
2234 if (unlikely(!ret)) return NULL;
2236 memcpy(ret, p, len);
2237 ret[len] = 0;
2239 _talloc_set_name_const(ret, ret);
2240 return ret;
2244 strdup with a talloc
2246 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
2248 if (unlikely(!p)) return NULL;
2249 return __talloc_strlendup(t, p, strlen(p));
2253 strndup with a talloc
2255 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
2257 if (unlikely(!p)) return NULL;
2258 return __talloc_strlendup(t, p, strnlen(p, n));
2261 static inline char *__talloc_strlendup_append(char *s, size_t slen,
2262 const char *a, size_t alen)
2264 char *ret;
2266 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
2267 if (unlikely(!ret)) return NULL;
2269 /* append the string and the trailing \0 */
2270 memcpy(&ret[slen], a, alen);
2271 ret[slen+alen] = 0;
2273 _talloc_set_name_const(ret, ret);
2274 return ret;
2278 * Appends at the end of the string.
2280 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
2282 if (unlikely(!s)) {
2283 return talloc_strdup(NULL, a);
2286 if (unlikely(!a)) {
2287 return s;
2290 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
2294 * Appends at the end of the talloc'ed buffer,
2295 * not the end of the string.
2297 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
2299 size_t slen;
2301 if (unlikely(!s)) {
2302 return talloc_strdup(NULL, a);
2305 if (unlikely(!a)) {
2306 return s;
2309 slen = talloc_get_size(s);
2310 if (likely(slen > 0)) {
2311 slen--;
2314 return __talloc_strlendup_append(s, slen, a, strlen(a));
2318 * Appends at the end of the string.
2320 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
2322 if (unlikely(!s)) {
2323 return talloc_strndup(NULL, a, n);
2326 if (unlikely(!a)) {
2327 return s;
2330 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
2334 * Appends at the end of the talloc'ed buffer,
2335 * not the end of the string.
2337 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
2339 size_t slen;
2341 if (unlikely(!s)) {
2342 return talloc_strndup(NULL, a, n);
2345 if (unlikely(!a)) {
2346 return s;
2349 slen = talloc_get_size(s);
2350 if (likely(slen > 0)) {
2351 slen--;
2354 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
2357 #ifndef HAVE_VA_COPY
2358 #ifdef HAVE___VA_COPY
2359 #define va_copy(dest, src) __va_copy(dest, src)
2360 #else
2361 #define va_copy(dest, src) (dest) = (src)
2362 #endif
2363 #endif
2365 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
2367 int len;
2368 char *ret;
2369 va_list ap2;
2370 char buf[1024];
2372 /* this call looks strange, but it makes it work on older solaris boxes */
2373 va_copy(ap2, ap);
2374 len = vsnprintf(buf, sizeof(buf), fmt, ap2);
2375 va_end(ap2);
2376 if (unlikely(len < 0)) {
2377 return NULL;
2380 ret = (char *)__talloc(t, len+1);
2381 if (unlikely(!ret)) return NULL;
2383 if (len < sizeof(buf)) {
2384 memcpy(ret, buf, len+1);
2385 } else {
2386 va_copy(ap2, ap);
2387 vsnprintf(ret, len+1, fmt, ap2);
2388 va_end(ap2);
2391 _talloc_set_name_const(ret, ret);
2392 return ret;
2397 Perform string formatting, and return a pointer to newly allocated
2398 memory holding the result, inside a memory pool.
2400 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
2402 va_list ap;
2403 char *ret;
2405 va_start(ap, fmt);
2406 ret = talloc_vasprintf(t, fmt, ap);
2407 va_end(ap);
2408 return ret;
2411 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2412 const char *fmt, va_list ap)
2413 PRINTF_ATTRIBUTE(3,0);
2415 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2416 const char *fmt, va_list ap)
2418 ssize_t alen;
2419 va_list ap2;
2420 char c;
2422 va_copy(ap2, ap);
2423 alen = vsnprintf(&c, 1, fmt, ap2);
2424 va_end(ap2);
2426 if (alen <= 0) {
2427 /* Either the vsnprintf failed or the format resulted in
2428 * no characters being formatted. In the former case, we
2429 * ought to return NULL, in the latter we ought to return
2430 * the original string. Most current callers of this
2431 * function expect it to never return NULL.
2433 return s;
2436 s = talloc_realloc(NULL, s, char, slen + alen + 1);
2437 if (!s) return NULL;
2439 va_copy(ap2, ap);
2440 vsnprintf(s + slen, alen + 1, fmt, ap2);
2441 va_end(ap2);
2443 _talloc_set_name_const(s, s);
2444 return s;
2448 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2449 * and return @p s, which may have moved. Good for gradually
2450 * accumulating output into a string buffer. Appends at the end
2451 * of the string.
2453 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2455 if (unlikely(!s)) {
2456 return talloc_vasprintf(NULL, fmt, ap);
2459 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2463 * Realloc @p s to append the formatted result of @p fmt and @p ap,
2464 * and return @p s, which may have moved. Always appends at the
2465 * end of the talloc'ed buffer, not the end of the string.
2467 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2469 size_t slen;
2471 if (unlikely(!s)) {
2472 return talloc_vasprintf(NULL, fmt, ap);
2475 slen = talloc_get_size(s);
2476 if (likely(slen > 0)) {
2477 slen--;
2480 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
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 string buffer.
2488 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2490 va_list ap;
2492 va_start(ap, fmt);
2493 s = talloc_vasprintf_append(s, fmt, ap);
2494 va_end(ap);
2495 return s;
2499 Realloc @p s to append the formatted result of @p fmt and return @p
2500 s, which may have moved. Good for gradually accumulating output
2501 into a buffer.
2503 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2505 va_list ap;
2507 va_start(ap, fmt);
2508 s = talloc_vasprintf_append_buffer(s, fmt, ap);
2509 va_end(ap);
2510 return s;
2514 alloc an array, checking for integer overflow in the array size
2516 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2518 if (count >= MAX_TALLOC_SIZE/el_size) {
2519 return NULL;
2521 return _talloc_named_const(ctx, el_size * count, name);
2525 alloc an zero array, checking for integer overflow in the array size
2527 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2529 if (count >= MAX_TALLOC_SIZE/el_size) {
2530 return NULL;
2532 return _talloc_zero(ctx, el_size * count, name);
2536 realloc an array, checking for integer overflow in the array size
2538 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2540 if (count >= MAX_TALLOC_SIZE/el_size) {
2541 return NULL;
2543 return _talloc_realloc(ctx, ptr, el_size * count, name);
2547 a function version of talloc_realloc(), so it can be passed as a function pointer
2548 to libraries that want a realloc function (a realloc function encapsulates
2549 all the basic capabilities of an allocation library, which is why this is useful)
2551 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2553 return _talloc_realloc(context, ptr, size, NULL);
2557 static int talloc_autofree_destructor(void *ptr)
2559 autofree_context = NULL;
2560 return 0;
2563 static void talloc_autofree(void)
2565 talloc_free(autofree_context);
2569 return a context which will be auto-freed on exit
2570 this is useful for reducing the noise in leak reports
2572 _PUBLIC_ void *talloc_autofree_context(void)
2574 if (autofree_context == NULL) {
2575 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2576 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2577 atexit(talloc_autofree);
2579 return autofree_context;
2582 _PUBLIC_ size_t talloc_get_size(const void *context)
2584 struct talloc_chunk *tc;
2586 if (context == NULL) {
2587 context = null_context;
2589 if (context == NULL) {
2590 return 0;
2593 tc = talloc_chunk_from_ptr(context);
2595 return tc->size;
2599 find a parent of this context that has the given name, if any
2601 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2603 struct talloc_chunk *tc;
2605 if (context == NULL) {
2606 return NULL;
2609 tc = talloc_chunk_from_ptr(context);
2610 while (tc) {
2611 if (tc->name && strcmp(tc->name, name) == 0) {
2612 return TC_PTR_FROM_CHUNK(tc);
2614 while (tc && tc->prev) tc = tc->prev;
2615 if (tc) {
2616 tc = tc->parent;
2619 return NULL;
2623 show the parentage of a context
2625 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2627 struct talloc_chunk *tc;
2629 if (context == NULL) {
2630 fprintf(file, "talloc no parents for NULL\n");
2631 return;
2634 tc = talloc_chunk_from_ptr(context);
2635 fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context));
2636 while (tc) {
2637 fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2638 while (tc && tc->prev) tc = tc->prev;
2639 if (tc) {
2640 tc = tc->parent;
2643 fflush(file);
2647 return 1 if ptr is a parent of context
2649 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2651 struct talloc_chunk *tc;
2653 if (context == NULL) {
2654 return 0;
2657 tc = talloc_chunk_from_ptr(context);
2658 while (tc) {
2659 if (depth <= 0) {
2660 return 0;
2662 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2663 while (tc && tc->prev) tc = tc->prev;
2664 if (tc) {
2665 tc = tc->parent;
2666 depth--;
2669 return 0;
2673 return 1 if ptr is a parent of context
2675 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2677 return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2681 return the total size of memory used by this context and all children
2683 static inline size_t _talloc_total_limit_size(const void *ptr,
2684 struct talloc_memlimit *old_limit,
2685 struct talloc_memlimit *new_limit)
2687 return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT,
2688 old_limit, new_limit);
2691 static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
2693 struct talloc_memlimit *l;
2695 for (l = limit; l != NULL; l = l->upper) {
2696 if (l->max_size != 0 &&
2697 ((l->max_size <= l->cur_size) ||
2698 (l->max_size - l->cur_size < size))) {
2699 return false;
2703 return true;
2707 Update memory limits when freeing a talloc_chunk.
2709 static void talloc_memlimit_update_on_free(struct talloc_chunk *tc)
2711 size_t limit_shrink_size;
2713 if (!tc->limit) {
2714 return;
2718 * Pool entries don't count. Only the pools
2719 * themselves are counted as part of the memory
2720 * limits. Note that this also takes care of
2721 * nested pools which have both flags
2722 * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set.
2724 if (tc->flags & TALLOC_FLAG_POOLMEM) {
2725 return;
2729 * If we are part of a memory limited context hierarchy
2730 * we need to subtract the memory used from the counters
2733 limit_shrink_size = tc->size+TC_HDR_SIZE;
2736 * If we're deallocating a pool, take into
2737 * account the prefix size added for the pool.
2740 if (tc->flags & TALLOC_FLAG_POOL) {
2741 limit_shrink_size += TP_HDR_SIZE;
2744 talloc_memlimit_shrink(tc->limit, limit_shrink_size);
2746 if (tc->limit->parent == tc) {
2747 free(tc->limit);
2750 tc->limit = NULL;
2754 Increase memory limit accounting after a malloc/realloc.
2756 static void talloc_memlimit_grow(struct talloc_memlimit *limit,
2757 size_t size)
2759 struct talloc_memlimit *l;
2761 for (l = limit; l != NULL; l = l->upper) {
2762 size_t new_cur_size = l->cur_size + size;
2763 if (new_cur_size < l->cur_size) {
2764 talloc_abort("logic error in talloc_memlimit_grow\n");
2765 return;
2767 l->cur_size = new_cur_size;
2772 Decrease memory limit accounting after a free/realloc.
2774 static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
2775 size_t size)
2777 struct talloc_memlimit *l;
2779 for (l = limit; l != NULL; l = l->upper) {
2780 if (l->cur_size < size) {
2781 talloc_abort("logic error in talloc_memlimit_shrink\n");
2782 return;
2784 l->cur_size = l->cur_size - size;
2788 _PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
2790 struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
2791 struct talloc_memlimit *orig_limit;
2792 struct talloc_memlimit *limit = NULL;
2794 if (tc->limit && tc->limit->parent == tc) {
2795 tc->limit->max_size = max_size;
2796 return 0;
2798 orig_limit = tc->limit;
2800 limit = malloc(sizeof(struct talloc_memlimit));
2801 if (limit == NULL) {
2802 return 1;
2804 limit->parent = tc;
2805 limit->max_size = max_size;
2806 limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit);
2808 if (orig_limit) {
2809 limit->upper = orig_limit;
2810 } else {
2811 limit->upper = NULL;
2814 return 0;