X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftalloc%2Ftalloc.h;h=e4f15aeecbb1b9dde7909525da89e88c727936e9;hp=2c55a12a987d4c0d4b2c83b993e85cf775d140bc;hb=d707abbb2ff707dd34aa77c9028f23f2266f8d5f;hpb=00ea3f8294da91eeea13f000ebb316f49610def4 diff --git a/ccan/talloc/talloc.h b/ccan/talloc/talloc.h index 2c55a12a..e4f15aee 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 @@ -172,7 +196,7 @@ int talloc_free(void *ptr); * talloc, talloc_free */ #define talloc_set_destructor(ptr, function) \ - _talloc_set_destructor((ptr), typesafe_cb(int, (function), (ptr))) + _talloc_set_destructor((ptr), typesafe_cb_def(int, (function), (ptr))) /** * talloc_zero - allocate zeroed dynamic memory for a type @@ -917,6 +941,8 @@ void *talloc_find_parent_byname(const void *ctx, const char *name); * 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_add_external() creates a node which uses a separate allocator. All * children allocated from that node will also use that allocator. @@ -924,32 +950,21 @@ void *talloc_find_parent_byname(const void *ctx, const char *name); * 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. + * * The parent pointers in realloc is the talloc pointer of the parent, if any. */ void *talloc_add_external(const void *ctx, void *(*realloc)(const void *parent, - void *ptr, size_t)); - -/** - * talloc_locksafe - set locking for talloc on shared memory - * @lock: function to use to lock memory - * @unlock: function to use to unlock memory - * @data: pointer to hand to @lock and @unlock - * - * If talloc is actually dealing with shared memory (threads or shared - * memory using talloc_add_external()) then locking is required on - * allocation and free to avoid corruption. - * - * These hooks allow a very course-grained locking scheme: @lock is - * called before any internal alloc or free, and @unlock is called - * after. */ -#define talloc_locksafe(lock, unlock, data) \ - _talloc_locksafe(typesafe_cb(void, lock, data), \ - typesafe_cb(void, unlock, data), \ - data) + 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); @@ -967,6 +982,5 @@ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned void *talloc_realloc_fn(const void *context, void *ptr, size_t size); void talloc_show_parents(const void *context, FILE *file); int talloc_is_parent(const void *context, const void *ptr); -void _talloc_locksafe(void (*lock)(void *), void (*unlock)(void *), void *); #endif /* CCAN_TALLOC_H */