-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtalloc.h
1934 lines (1834 loc) · 62.1 KB
/
talloc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef _TALLOC_H_
#define _TALLOC_H_
/*
Unix SMB/CIFS implementation.
Samba temporary memory allocation functions
Copyright (C) Andrew Tridgell 2004-2005
Copyright (C) Stefan Metzmacher 2006
** NOTE! The following LGPL license applies to the talloc
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup talloc The talloc API
*
* talloc is a hierarchical, reference counted memory pool system with
* destructors. It is the core memory allocator used in Samba.
*
* @{
*/
#define TALLOC_VERSION_MAJOR 2
#define TALLOC_VERSION_MINOR 1
int talloc_version_major(void);
int talloc_version_minor(void);
/* This is mostly useful only for testing */
int talloc_test_get_magic(void);
/**
* @brief Define a talloc parent type
*
* As talloc is a hierarchial memory allocator, every talloc chunk is a
* potential parent to other talloc chunks. So defining a separate type for a
* talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless,
* as it provides an indicator for function arguments. You will frequently
* write code like
*
* @code
* struct foo *foo_create(TALLOC_CTX *mem_ctx)
* {
* struct foo *result;
* result = talloc(mem_ctx, struct foo);
* if (result == NULL) return NULL;
* ... initialize foo ...
* return result;
* }
* @endcode
*
* In this type of allocating functions it is handy to have a general
* TALLOC_CTX type to indicate which parent to put allocated structures on.
*/
typedef void TALLOC_CTX;
/*
this uses a little trick to allow __LINE__ to be stringified
*/
#ifndef __location__
#define __TALLOC_STRING_LINE1__(s) #s
#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s)
#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__)
#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
#endif
#ifndef TALLOC_DEPRECATED
#define TALLOC_DEPRECATED 0
#endif
#ifndef PRINTF_ATTRIBUTE
#if (__GNUC__ >= 3)
/** Use gcc attribute to check printf fns. a1 is the 1-based index of
* the parameter containing the format, and a2 the index of the first
* argument. Note that some gcc 2.x versions don't handle this
* properly **/
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
#else
#define PRINTF_ATTRIBUTE(a1, a2)
#endif
#endif
#ifdef DOXYGEN
/**
* @brief Create a new talloc context.
*
* The talloc() macro is the core of the talloc library. It takes a memory
* context and a type, and returns a pointer to a new area of memory of the
* given type.
*
* The returned pointer is itself a talloc context, so you can use it as the
* context argument to more calls to talloc if you wish.
*
* The returned pointer is a "child" of the supplied context. This means that if
* you talloc_free() the context then the new child disappears as well.
* Alternatively you can free just the child.
*
* @param[in] ctx A talloc context to create a new reference on or NULL to
* create a new top level context.
*
* @param[in] type The type of memory to allocate.
*
* @return A type casted talloc context or NULL on error.
*
* @code
* unsigned int *a, *b;
*
* a = talloc(NULL, unsigned int);
* b = talloc(a, unsigned int);
* @endcode
*
* @see talloc_zero
* @see talloc_array
* @see talloc_steal
* @see talloc_free
*/
void *talloc(const void *ctx, #type);
#else
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
void *_talloc(const void *context, size_t size);
#endif
/**
* @brief Create a new top level talloc context.
*
* This function creates a zero length named talloc context as a top level
* context. It is equivalent to:
*
* @code
* talloc_named(NULL, 0, fmt, ...);
* @endcode
* @param[in] fmt Format string for the name.
*
* @param[in] ... Additional printf-style arguments.
*
* @return The allocated memory chunk, NULL on error.
*
* @see talloc_named()
*/
void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
#ifdef DOXYGEN
/**
* @brief Free a chunk of talloc memory.
*
* The talloc_free() function frees a piece of talloc memory, and all its
* children. You can call talloc_free() on any pointer returned by
* talloc().
*
* The return value of talloc_free() indicates success or failure, with 0
* returned for success and -1 for failure. A possible failure condition
* is if the pointer had a destructor attached to it and the destructor
* returned -1. See talloc_set_destructor() for details on
* destructors. Likewise, if "ptr" is NULL, then the function will make
* no modifications and return -1.
*
* From version 2.0 and onwards, as a special case, talloc_free() is
* refused on pointers that have more than one parent associated, as talloc
* would have no way of knowing which parent should be removed. This is
* different from older versions in the sense that always the reference to
* the most recently established parent has been destroyed. Hence to free a
* pointer that has more than one parent please use talloc_unlink().
*
* To help you find problems in your code caused by this behaviour, if
* you do try and free a pointer with more than one parent then the
* talloc logging function will be called to give output like this:
*
* @code
* ERROR: talloc_free with references at some_dir/source/foo.c:123
* reference at some_dir/source/other.c:325
* reference at some_dir/source/third.c:121
* @endcode
*
* Please see the documentation for talloc_set_log_fn() and
* talloc_set_log_stderr() for more information on talloc logging
* functions.
*
* If <code>TALLOC_FREE_FILL</code> environment variable is set,
* the memory occupied by the context is filled with the value of this variable.
* The value should be a numeric representation of the character you want to
* use.
*
* talloc_free() operates recursively on its children.
*
* @param[in] ptr The chunk to be freed.
*
* @return Returns 0 on success and -1 on error. A possible
* failure condition is if the pointer had a destructor
* attached to it and the destructor returned -1. Likewise,
* if "ptr" is NULL, then the function will make no
* modifications and returns -1.
*
* Example:
* @code
* unsigned int *a, *b;
* a = talloc(NULL, unsigned int);
* b = talloc(a, unsigned int);
*
* talloc_free(a); // Frees a and b
* @endcode
*
* @see talloc_set_destructor()
* @see talloc_unlink()
*/
int talloc_free(void *ptr);
#else
#define talloc_free(ctx) _talloc_free(ctx, __location__)
int _talloc_free(void *ptr, const char *location);
#endif
/**
* @brief Free a talloc chunk's children.
*
* The function walks along the list of all children of a talloc context and
* talloc_free()s only the children, not the context itself.
*
* A NULL argument is handled as no-op.
*
* @param[in] ptr The chunk that you want to free the children of
* (NULL is allowed too)
*/
void talloc_free_children(void *ptr);
#ifdef DOXYGEN
/**
* @brief Assign a destructor function to be called when a chunk is freed.
*
* The function talloc_set_destructor() sets the "destructor" for the pointer
* "ptr". A destructor is a function that is called when the memory used by a
* pointer is about to be released. The destructor receives the pointer as an
* argument, and should return 0 for success and -1 for failure.
*
* The destructor can do anything it wants to, including freeing other pieces
* of memory. A common use for destructors is to clean up operating system
* resources (such as open file descriptors) contained in the structure the
* destructor is placed on.
*
* You can only place one destructor on a pointer. If you need more than one
* destructor then you can create a zero-length child of the pointer and place
* an additional destructor on that.
*
* To remove a destructor call talloc_set_destructor() with NULL for the
* destructor.
*
* If your destructor attempts to talloc_free() the pointer that it is the
* destructor for then talloc_free() will return -1 and the free will be
* ignored. This would be a pointless operation anyway, as the destructor is
* only called when the memory is just about to go away.
*
* @param[in] ptr The talloc chunk to add a destructor to.
*
* @param[in] destructor The destructor function to be called. NULL to remove
* it.
*
* Example:
* @code
* static int destroy_fd(int *fd) {
* close(*fd);
* return 0;
* }
*
* int *open_file(const char *filename) {
* int *fd = talloc(NULL, int);
* *fd = open(filename, O_RDONLY);
* if (*fd < 0) {
* talloc_free(fd);
* return NULL;
* }
* // Whenever they free this, we close the file.
* talloc_set_destructor(fd, destroy_fd);
* return fd;
* }
* @endcode
*
* @see talloc()
* @see talloc_free()
*/
void talloc_set_destructor(const void *ptr, int (*destructor)(void *));
/**
* @brief Change a talloc chunk's parent.
*
* The talloc_steal() function changes the parent context of a talloc
* pointer. It is typically used when the context that the pointer is
* currently a child of is going to be freed and you wish to keep the
* memory for a longer time.
*
* To make the changed hierarchy less error-prone, you might consider to use
* talloc_move().
*
* If you try and call talloc_steal() on a pointer that has more than one
* parent then the result is ambiguous. Talloc will choose to remove the
* parent that is currently indicated by talloc_parent() and replace it with
* the chosen parent. You will also get a message like this via the talloc
* logging functions:
*
* @code
* WARNING: talloc_steal with references at some_dir/source/foo.c:123
* reference at some_dir/source/other.c:325
* reference at some_dir/source/third.c:121
* @endcode
*
* To unambiguously change the parent of a pointer please see the function
* talloc_reparent(). See the talloc_set_log_fn() documentation for more
* information on talloc logging.
*
* @param[in] new_ctx The new parent context.
*
* @param[in] ptr The talloc chunk to move.
*
* @return Returns the pointer that you pass it. It does not have
* any failure modes.
*
* @note It is possible to produce loops in the parent/child relationship
* if you are not careful with talloc_steal(). No guarantees are provided
* as to your sanity or the safety of your data if you do this.
*/
void *talloc_steal(const void *new_ctx, const void *ptr);
#else /* DOXYGEN */
/* try to make talloc_set_destructor() and talloc_steal() type safe,
if we have a recent gcc */
#if (__GNUC__ >= 3)
#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
#define talloc_set_destructor(ptr, function) \
do { \
int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \
_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
} while(0)
/* this extremely strange macro is to avoid some braindamaged warning
stupidity in gcc 4.1.x */
#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__); __talloc_steal_ret; })
#else /* __GNUC__ >= 3 */
#define talloc_set_destructor(ptr, function) \
_talloc_set_destructor((ptr), (int (*)(void *))(function))
#define _TALLOC_TYPEOF(ptr) void *
#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__)
#endif /* __GNUC__ >= 3 */
void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location);
#endif /* DOXYGEN */
/**
* @brief Assign a name to a talloc chunk.
*
* Each talloc pointer has a "name". The name is used principally for
* debugging purposes, although it is also possible to set and get the name on
* a pointer in as a way of "marking" pointers in your code.
*
* The main use for names on pointer is for "talloc reports". See
* talloc_report() and talloc_report_full() for details. Also see
* talloc_enable_leak_report() and talloc_enable_leak_report_full().
*
* The talloc_set_name() function allocates memory as a child of the
* pointer. It is logically equivalent to:
*
* @code
* talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...));
* @endcode
*
* @param[in] ptr The talloc chunk to assign a name to.
*
* @param[in] fmt Format string for the name.
*
* @param[in] ... Add printf-style additional arguments.
*
* @return The assigned name, NULL on error.
*
* @note Multiple calls to talloc_set_name() will allocate more memory without
* releasing the name. All of the memory is released when the ptr is freed
* using talloc_free().
*/
const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
#ifdef DOXYGEN
/**
* @brief Change a talloc chunk's parent.
*
* This function has the same effect as talloc_steal(), and additionally sets
* the source pointer to NULL. You would use it like this:
*
* @code
* struct foo *X = talloc(tmp_ctx, struct foo);
* struct foo *Y;
* Y = talloc_move(new_ctx, &X);
* @endcode
*
* @param[in] new_ctx The new parent context.
*
* @param[in] pptr Pointer to a pointer to the talloc chunk to move.
*
* @return The pointer to the talloc chunk that moved.
* It does not have any failure modes.
*
*/
void *talloc_move(const void *new_ctx, void **pptr);
#else
#define talloc_move(ctx, pptr) (_TALLOC_TYPEOF(*(pptr)))_talloc_move((ctx),(void *)(pptr))
void *_talloc_move(const void *new_ctx, const void *pptr);
#endif
/**
* @brief Assign a name to a talloc chunk.
*
* The function is just like talloc_set_name(), but it takes a string constant,
* and is much faster. It is extensively used by the "auto naming" macros, such
* as talloc_p().
*
* This function does not allocate any memory. It just copies the supplied
* pointer into the internal representation of the talloc ptr. This means you
* must not pass a name pointer to memory that will disappear before the ptr
* is freed with talloc_free().
*
* @param[in] ptr The talloc chunk to assign a name to.
*
* @param[in] name Format string for the name.
*/
void talloc_set_name_const(const void *ptr, const char *name);
/**
* @brief Create a named talloc chunk.
*
* The talloc_named() function creates a named talloc pointer. It is
* equivalent to:
*
* @code
* ptr = talloc_size(context, size);
* talloc_set_name(ptr, fmt, ....);
* @endcode
*
* @param[in] context The talloc context to hang the result off.
*
* @param[in] size Number of char's that you want to allocate.
*
* @param[in] fmt Format string for the name.
*
* @param[in] ... Additional printf-style arguments.
*
* @return The allocated memory chunk, NULL on error.
*
* @see talloc_set_name()
*/
void *talloc_named(const void *context, size_t size,
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
/**
* @brief Basic routine to allocate a chunk of memory.
*
* This is equivalent to:
*
* @code
* ptr = talloc_size(context, size);
* talloc_set_name_const(ptr, name);
* @endcode
*
* @param[in] context The parent context.
*
* @param[in] size The number of char's that we want to allocate.
*
* @param[in] name The name the talloc block has.
*
* @return The allocated memory chunk, NULL on error.
*/
void *talloc_named_const(const void *context, size_t size, const char *name);
#ifdef DOXYGEN
/**
* @brief Untyped allocation.
*
* The function should be used when you don't have a convenient type to pass to
* talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so
* you are on your own for type checking.
*
* Best to use talloc() or talloc_array() instead.
*
* @param[in] ctx The talloc context to hang the result off.
*
* @param[in] size Number of char's that you want to allocate.
*
* @return The allocated memory chunk, NULL on error.
*
* Example:
* @code
* void *mem = talloc_size(NULL, 100);
* @endcode
*/
void *talloc_size(const void *ctx, size_t size);
#else
#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
#endif
#ifdef DOXYGEN
/**
* @brief Allocate into a typed pointer.
*
* The talloc_ptrtype() macro should be used when you have a pointer and want
* to allocate memory to point at with this pointer. When compiling with
* gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and
* talloc_get_name() will return the current location in the source file and
* not the type.
*
* @param[in] ctx The talloc context to hang the result off.
*
* @param[in] type The pointer you want to assign the result to.
*
* @return The properly casted allocated memory chunk, NULL on
* error.
*
* Example:
* @code
* unsigned int *a = talloc_ptrtype(NULL, a);
* @endcode
*/
void *talloc_ptrtype(const void *ctx, #type);
#else
#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
#endif
#ifdef DOXYGEN
/**
* @brief Allocate a new 0-sized talloc chunk.
*
* This is a utility macro that creates a new memory context hanging off an
* existing context, automatically naming it "talloc_new: __location__" where
* __location__ is the source line it is called from. It is particularly
* useful for creating a new temporary working context.
*
* @param[in] ctx The talloc parent context.
*
* @return A new talloc chunk, NULL on error.
*/
void *talloc_new(const void *ctx);
#else
#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
#endif
#ifdef DOXYGEN
/**
* @brief Allocate a 0-initizialized structure.
*
* The macro is equivalent to:
*
* @code
* ptr = talloc(ctx, type);
* if (ptr) memset(ptr, 0, sizeof(type));
* @endcode
*
* @param[in] ctx The talloc context to hang the result off.
*
* @param[in] type The type that we want to allocate.
*
* @return Pointer to a piece of memory, properly cast to 'type *',
* NULL on error.
*
* Example:
* @code
* unsigned int *a, *b;
* a = talloc_zero(NULL, unsigned int);
* b = talloc_zero(a, unsigned int);
* @endcode
*
* @see talloc()
* @see talloc_zero_size()
* @see talloc_zero_array()
*/
void *talloc_zero(const void *ctx, #type);
/**
* @brief Allocate untyped, 0-initialized memory.
*
* @param[in] ctx The talloc context to hang the result off.
*
* @param[in] size Number of char's that you want to allocate.
*
* @return The allocated memory chunk.
*/
void *talloc_zero_size(const void *ctx, size_t size);
#else
#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
void *_talloc_zero(const void *ctx, size_t size, const char *name);
#endif
/**
* @brief Return the name of a talloc chunk.
*
* @param[in] ptr The talloc chunk.
*
* @return The current name for the given talloc pointer.
*
* @see talloc_set_name()
*/
const char *talloc_get_name(const void *ptr);
/**
* @brief Verify that a talloc chunk carries a specified name.
*
* This function checks if a pointer has the specified name. If it does
* then the pointer is returned.
*
* @param[in] ptr The talloc chunk to check.
*
* @param[in] name The name to check against.
*
* @return The pointer if the name matches, NULL if it doesn't.
*/
void *talloc_check_name(const void *ptr, const char *name);
/**
* @brief Get the parent chunk of a pointer.
*
* @param[in] ptr The talloc pointer to inspect.
*
* @return The talloc parent of ptr, NULL on error.
*/
void *talloc_parent(const void *ptr);
/**
* @brief Get a talloc chunk's parent name.
*
* @param[in] ptr The talloc pointer to inspect.
*
* @return The name of ptr's parent chunk.
*/
const char *talloc_parent_name(const void *ptr);
/**
* @brief Get the total size of a talloc chunk including its children.
*
* The function returns the total size in bytes used by this pointer and all
* child pointers. Mostly useful for debugging.
*
* Passing NULL is allowed, but it will only give a meaningful result if
* talloc_enable_leak_report() or talloc_enable_leak_report_full() has
* been called.
*
* @param[in] ptr The talloc chunk.
*
* @return The total size.
*/
size_t talloc_total_size(const void *ptr);
/**
* @brief Get the number of talloc chunks hanging off a chunk.
*
* The talloc_total_blocks() function returns the total memory block
* count used by this pointer and all child pointers. Mostly useful for
* debugging.
*
* Passing NULL is allowed, but it will only give a meaningful result if
* talloc_enable_leak_report() or talloc_enable_leak_report_full() has
* been called.
*
* @param[in] ptr The talloc chunk.
*
* @return The total size.
*/
size_t talloc_total_blocks(const void *ptr);
#ifdef DOXYGEN
/**
* @brief Duplicate a memory area into a talloc chunk.
*
* The function is equivalent to:
*
* @code
* ptr = talloc_size(ctx, size);
* if (ptr) memcpy(ptr, p, size);
* @endcode
*
* @param[in] t The talloc context to hang the result off.
*
* @param[in] p The memory chunk you want to duplicate.
*
* @param[in] size Number of char's that you want copy.
*
* @return The allocated memory chunk.
*
* @see talloc_size()
*/
void *talloc_memdup(const void *t, const void *p, size_t size);
#else
#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
#endif
#ifdef DOXYGEN
/**
* @brief Assign a type to a talloc chunk.
*
* This macro allows you to force the name of a pointer to be of a particular
* type. This can be used in conjunction with talloc_get_type() to do type
* checking on void* pointers.
*
* It is equivalent to this:
*
* @code
* talloc_set_name_const(ptr, #type)
* @endcode
*
* @param[in] ptr The talloc chunk to assign the type to.
*
* @param[in] type The type to assign.
*/
void talloc_set_type(const char *ptr, #type);
/**
* @brief Get a typed pointer out of a talloc pointer.
*
* This macro allows you to do type checking on talloc pointers. It is
* particularly useful for void* private pointers. It is equivalent to
* this:
*
* @code
* (type *)talloc_check_name(ptr, #type)
* @endcode
*
* @param[in] ptr The talloc pointer to check.
*
* @param[in] type The type to check against.
*
* @return The properly casted pointer given by ptr, NULL on error.
*/
type *talloc_get_type(const void *ptr, #type);
#else
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
#endif
#ifdef DOXYGEN
/**
* @brief Safely turn a void pointer into a typed pointer.
*
* This macro is used together with talloc(mem_ctx, struct foo). If you had to
* assign the talloc chunk pointer to some void pointer variable,
* talloc_get_type_abort() is the recommended way to get the convert the void
* pointer back to a typed pointer.
*
* @param[in] ptr The void pointer to convert.
*
* @param[in] type The type that this chunk contains
*
* @return The same value as ptr, type-checked and properly cast.
*/
void *talloc_get_type_abort(const void *ptr, #type);
#else
#ifdef TALLOC_GET_TYPE_ABORT_NOOP
#define talloc_get_type_abort(ptr, type) (type *)(ptr)
#else
#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
#endif
void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
#endif
/**
* @brief Find a parent context by name.
*
* Find a parent memory context of the current context that has the given
* name. This can be very useful in complex programs where it may be
* difficult to pass all information down to the level you need, but you
* know the structure you want is a parent of another context.
*
* @param[in] ctx The talloc chunk to start from.
*
* @param[in] name The name of the parent we look for.
*
* @return The memory context we are looking for, NULL if not
* found.
*/
void *talloc_find_parent_byname(const void *ctx, const char *name);
#ifdef DOXYGEN
/**
* @brief Find a parent context by type.
*
* Find a parent memory context of the current context that has the given
* name. This can be very useful in complex programs where it may be
* difficult to pass all information down to the level you need, but you
* know the structure you want is a parent of another context.
*
* Like talloc_find_parent_byname() but takes a type, making it typesafe.
*
* @param[in] ptr The talloc chunk to start from.
*
* @param[in] type The type of the parent to look for.
*
* @return The memory context we are looking for, NULL if not
* found.
*/
void *talloc_find_parent_bytype(const void *ptr, #type);
#else
#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
#endif
/**
* @brief Allocate a talloc pool.
*
* A talloc pool is a pure optimization for specific situations. In the
* release process for Samba 3.2 we found out that we had become considerably
* slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU
* consumer in benchmarks. For Samba 3.2 we have internally converted many
* static buffers to dynamically allocated ones, so malloc(3) being beaten
* more was no surprise. But it made us slower.
*
* talloc_pool() is an optimization to call malloc(3) a lot less for the use
* pattern Samba has: The SMB protocol is mainly a request/response protocol
* where we have to allocate a certain amount of memory per request and free
* that after the SMB reply is sent to the client.
*
* talloc_pool() creates a talloc chunk that you can use as a talloc parent
* exactly as you would use any other ::TALLOC_CTX. The difference is that
* when you talloc a child of this pool, no malloc(3) is done. Instead, talloc
* just increments a pointer inside the talloc_pool. This also works
* recursively. If you use the child of the talloc pool as a parent for
* grand-children, their memory is also taken from the talloc pool.
*
* If there is not enough memory in the pool to allocate the new child,
* it will create a new talloc chunk as if the parent was a normal talloc
* context.
*
* If you talloc_free() children of a talloc pool, the memory is not given
* back to the system. Instead, free(3) is only called if the talloc_pool()
* itself is released with talloc_free().
*
* The downside of a talloc pool is that if you talloc_move() a child of a
* talloc pool to a talloc parent outside the pool, the whole pool memory is
* not free(3)'ed until that moved chunk is also talloc_free()ed.
*
* @param[in] context The talloc context to hang the result off.
*
* @param[in] size Size of the talloc pool.
*
* @return The allocated talloc pool, NULL on error.
*/
void *talloc_pool(const void *context, size_t size);
#ifdef DOXYGEN
/**
* @brief Allocate a talloc object as/with an additional pool.
*
* This is like talloc_pool(), but's it's more flexible
* and allows an object to be a pool for its children.
*
* @param[in] ctx The talloc context to hang the result off.
*
* @param[in] type The type that we want to allocate.
*
* @param[in] num_subobjects The expected number of subobjects, which will
* be allocated within the pool. This allocates
* space for talloc_chunk headers.
*
* @param[in] total_subobjects_size The size that all subobjects can use in total.
*
*
* @return The allocated talloc object, NULL on error.
*/
void *talloc_pooled_object(const void *ctx, #type,
unsigned num_subobjects,
size_t total_subobjects_size);
#else
#define talloc_pooled_object(_ctx, _type, \
_num_subobjects, \
_total_subobjects_size) \
(_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \
(_num_subobjects), \
(_total_subobjects_size))
void *_talloc_pooled_object(const void *ctx,
size_t type_size,
const char *type_name,
unsigned num_subobjects,
size_t total_subobjects_size);
#endif
/**
* @brief Free a talloc chunk and NULL out the pointer.
*
* TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want
* immediate feedback (i.e. crash) if you use a pointer after having free'ed
* it.
*
* @param[in] ctx The chunk to be freed.
*/
#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0)
/* @} ******************************************************************/
/**
* \defgroup talloc_ref The talloc reference function.
* @ingroup talloc
*
* This module contains the definitions around talloc references
*
* @{
*/
/**
* @brief Increase the reference count of a talloc chunk.
*
* The talloc_increase_ref_count(ptr) function is exactly equivalent to:
*
* @code
* talloc_reference(NULL, ptr);
* @endcode
*
* You can use either syntax, depending on which you think is clearer in
* your code.
*
* @param[in] ptr The pointer to increase the reference count.
*
* @return 0 on success, -1 on error.
*/
int talloc_increase_ref_count(const void *ptr);
/**
* @brief Get the number of references to a talloc chunk.
*
* @param[in] ptr The pointer to retrieve the reference count from.
*
* @return The number of references.
*/
size_t talloc_reference_count(const void *ptr);
#ifdef DOXYGEN
/**
* @brief Create an additional talloc parent to a pointer.
*
* The talloc_reference() function makes "context" an additional parent of
* ptr. Each additional reference consumes around 48 bytes of memory on intel
* x86 platforms.
*
* If ptr is NULL, then the function is a no-op, and simply returns NULL.
*
* After creating a reference you can free it in one of the following ways:
*
* - you can talloc_free() any parent of the original pointer. That
* will reduce the number of parents of this pointer by 1, and will
* cause this pointer to be freed if it runs out of parents.
*
* - you can talloc_free() the pointer itself if it has at maximum one
* parent. This behaviour has been changed since the release of version
* 2.0. Further informations in the description of "talloc_free".
*
* For more control on which parent to remove, see talloc_unlink()
* @param[in] ctx The additional parent.
*
* @param[in] ptr The pointer you want to create an additional parent for.
*
* @return The original pointer 'ptr', NULL if talloc ran out of
* memory in creating the reference.
*
* @warning You should try to avoid using this interface. It turns a beautiful
* talloc-tree into a graph. It is often really hard to debug if you
* screw something up by accident.
*
* Example:
* @code
* unsigned int *a, *b, *c;
* a = talloc(NULL, unsigned int);
* b = talloc(NULL, unsigned int);
* c = talloc(a, unsigned int);
* // b also serves as a parent of c.
* talloc_reference(b, c);
* @endcode
*
* @see talloc_unlink()
*/
void *talloc_reference(const void *ctx, const void *ptr);
#else
#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference_loc((ctx),(ptr), __location__)
void *_talloc_reference_loc(const void *context, const void *ptr, const char *location);
#endif
/**
* @brief Remove a specific parent from a talloc chunk.
*
* The function removes a specific parent from ptr. The context passed must
* either be a context used in talloc_reference() with this pointer, or must be
* a direct parent of ptr.
*
* You can just use talloc_free() instead of talloc_unlink() if there