X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftalloc%2Ftalloc.h;h=54a702050e96d73409c8169e5ac58b11b359fc68;hb=99e576ac94fd86fcba188fb72ced9e8087ac1680;hp=8b0f8a38bc82d6782dbe29c2a56c4d3c1daaab63;hpb=16b7eb13fbcb1a04a71622e6310020baccc3c39c;p=ccan diff --git a/ccan/talloc/talloc.h b/ccan/talloc/talloc.h index 8b0f8a38..54a70205 100644 --- a/ccan/talloc/talloc.h +++ b/ccan/talloc/talloc.h @@ -26,8 +26,8 @@ #include #include #include +#include #include "config.h" -#include "ccan/typesafe_cb/typesafe_cb.h" /* this uses a little trick to allow __LINE__ to be stringified @@ -87,6 +87,30 @@ */ #define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) +/** + * talloc_set - allocate dynamic memory for a type, into a pointer + * @ptr: pointer to the pointer to assign. + * @ctx: context to be parent of this allocation, or NULL. + * + * talloc_set() does a talloc, but also adds a destructor which will make the + * pointer invalid when it is freed. This can find many use-after-free bugs. + * + * Note that the destructor is chained off a zero-length allocation, and so + * is not affected by talloc_set_destructor(). + * + * Example: + * unsigned int *a; + * a = talloc(NULL, unsigned int); + * talloc_set(&b, a, unsigned int); + * talloc_free(a); + * *b = 1; // This will crash! + * + * See Also: + * talloc. + */ +#define talloc_set(pptr, ctx) \ + _talloc_set((pptr), (ctx), sizeof(&**(pptr)), __location__) + /** * talloc_free - free talloc'ed memory and its children * @ptr: the talloced pointer to free @@ -119,7 +143,7 @@ * See Also: * talloc_set_destructor, talloc_unlink */ -int talloc_free(void *ptr); +int talloc_free(const void *ptr); /** * talloc_set_destructor: set a destructor for when this pointer is freed @@ -398,21 +422,6 @@ void talloc_report(const void *ptr, FILE *f); */ #define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) -/** - * talloc_free_children - free talloc'ed memory's children only - * @ptr: the talloced pointer whose children we want to free - * - * talloc_free_children() walks along the list of all children of a talloc - * context @ptr and talloc_free()s only the children, not the context itself. - * Example: - * unsigned int *a, *b; - * a = talloc(NULL, unsigned int); - * b = talloc(a, unsigned int); - * // Frees b - * talloc_free_children(a); - */ -void talloc_free_children(void *ptr); - /** * talloc_new - create a new context * @ctx: the context to use as a parent. @@ -929,33 +938,33 @@ size_t talloc_get_size(const void *ctx); void *talloc_find_parent_byname(const void *ctx, const char *name); /** - * talloc_external_enable - set external allocators for some nodes - * @alloc: the malloc() equivalent - * @free: the free() equivalent + * talloc_add_external - create an externally allocated node + * @ctx: the parent * @realloc: the realloc() equivalent + * @lock: the call to lock before manipulation of external nodes + * @unlock: the call to unlock after manipulation of external nodes * - * talloc_mark_external() can be used to mark nodes whose children should - * use separate allocators. Currently the set of allocators is global, not - * per-node, and is set with this function. + * talloc_add_external() creates a node which uses a separate allocator. All + * children allocated from that node will also use that allocator. * - * The parent pointers is the talloc pointer of the parent. - */ -void talloc_external_enable(void *(*alloc)(void *parent, size_t size), - void (*free)(void *ptr, void *parent), - void *(*realloc)(void *ptr, void *parent, size_t)); - -/** - * talloc_mark_external - children of this note must use external allocators - * @p: the talloc pointer + * Note: Currently there is only one external allocator, not per-node, + * and it is set with this function. + * + * @lock is handed a pointer which was previous returned from your realloc + * function; you should use that to figure out which lock to get if you have + * multiple external pools. * - * This function indicates that all children (and children's children etc) - * should use the allocators set up wth talloc_external_enable() rather than - * normal malloc/free. + * The parent pointers in realloc is the talloc pointer of the parent, if any. */ -void talloc_mark_external(void *ptr); +void *talloc_add_external(const void *ctx, + void *(*realloc)(const void *parent, + void *ptr, size_t), + void (*lock)(const void *p), + void (*unlock)(void)); /* The following definitions come from talloc.c */ void *_talloc(const void *context, size_t size); +void _talloc_set(void *ptr, const void *ctx, size_t size, const char *name); void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); size_t talloc_reference_count(const void *ptr); void *_talloc_reference(const void *context, const void *ptr);