talloc is a hierarchical, reference counted memory pool system with destructors. More...
Modules | |
The talloc reference function. | |
This module contains the definitions around talloc references. | |
The talloc array functions | |
Talloc contains some handy helpers for handling Arrays conveniently. | |
The talloc string functions. | |
talloc string allocation and manipulation functions. | |
The talloc debugging support functions | |
To aid memory debugging, talloc contains routines to inspect the currently allocated memory hierarchy. | |
Defines | |
#define | TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) |
Free a talloc chunk and NULL out the pointer. | |
Typedefs | |
typedef void | TALLOC_CTX |
Define a talloc parent type. | |
Functions | |
void * | talloc (const void *ctx,#type) |
Create a new talloc context. | |
void * | talloc_init (const char *fmt,...) |
Create a new top level talloc context. | |
int | talloc_free (void *ptr) |
Free a chunk of talloc memory. | |
void | talloc_free_children (void *ptr) |
Free a talloc chunk's children. | |
void | talloc_set_destructor (const void *ptr, int(*destructor)(void *)) |
Assign a destructor function to be called when a chunk is freed. | |
void * | talloc_steal (const void *new_ctx, const void *ptr) |
Change a talloc chunk's parent. | |
const char * | talloc_set_name (const void *ptr, const char *fmt,...) |
Assign a name to a talloc chunk. | |
void * | talloc_move (const void *new_ctx, void **pptr) |
Change a talloc chunk's parent. | |
void | talloc_set_name_const (const void *ptr, const char *name) |
Assign a name to a talloc chunk. | |
void * | talloc_named (const void *context, size_t size, const char *fmt,...) |
Create a named talloc chunk. | |
void * | talloc_named_const (const void *context, size_t size, const char *name) |
Basic routine to allocate a chunk of memory. | |
void * | talloc_size (const void *ctx, size_t size) |
Untyped allocation. | |
void * | talloc_ptrtype (const void *ctx,#type) |
Allocate into a typed pointer. | |
void * | talloc_new (const void *ctx) |
Allocate a new 0-sized talloc chunk. | |
void * | talloc_zero (const void *ctx,#type) |
Allocate a 0-initizialized structure. | |
void * | talloc_zero_size (const void *ctx, size_t size) |
Allocate untyped, 0-initialized memory. | |
const char * | talloc_get_name (const void *ptr) |
Return the name of a talloc chunk. | |
void * | talloc_check_name (const void *ptr, const char *name) |
Verify that a talloc chunk carries a specified name. | |
void * | talloc_parent (const void *ptr) |
Get the parent chunk of a pointer. | |
const char * | talloc_parent_name (const void *ptr) |
Get a talloc chunk's parent name. | |
size_t | talloc_total_size (const void *ptr) |
Get the total size of a talloc chunk including its children. | |
size_t | talloc_total_blocks (const void *ptr) |
Get the number of talloc chunks hanging off a chunk. | |
void * | talloc_memdup (const void *t, const void *p, size_t size) |
Duplicate a memory area into a talloc chunk. | |
void | talloc_set_type (const char *ptr,#type) |
Assign a type to a talloc chunk. | |
type * | talloc_get_type (const void *ptr,#type) |
Get a typed pointer out of a talloc pointer. | |
void * | talloc_get_type_abort (const void *ptr,#type) |
Safely turn a void pointer into a typed pointer. | |
void * | talloc_find_parent_byname (const void *ctx, const char *name) |
Find a parent context by name. | |
void * | talloc_find_parent_bytype (const void *ptr,#type) |
Find a parent context by type. | |
void * | talloc_pool (const void *context, size_t size) |
Allocate a talloc pool. | |
void * | talloc_pooled_object (const void *ctx,#type, unsigned num_subobjects, size_t total_subobjects_size) |
Allocate a talloc object as/with an additional pool. |
talloc is a hierarchical, reference counted memory pool system with destructors.
It is the core memory allocator used in Samba.
#define TALLOC_FREE | ( | ctx | ) | do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) |
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.
[in] | ctx | The chunk to be freed. |
typedef void TALLOC_CTX |
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
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; }
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.
void* talloc | ( | const void * | ctx, | |
# | type | |||
) |
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.
[in] | ctx | A talloc context to create a new reference on or NULL to create a new top level context. |
[in] | type | The type of memory to allocate. |
void* talloc_check_name | ( | const void * | ptr, | |
const char * | name | |||
) |
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.
[in] | ptr | The talloc chunk to check. |
[in] | name | The name to check against. |
void* talloc_find_parent_byname | ( | const void * | ctx, | |
const char * | name | |||
) |
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.
[in] | ctx | The talloc chunk to start from. |
[in] | name | The name of the parent we look for. |
void* talloc_find_parent_bytype | ( | const void * | ptr, | |
# | type | |||
) |
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.
[in] | ptr | The talloc chunk to start from. |
[in] | type | The type of the parent to look for. |
int talloc_free | ( | void * | ptr | ) |
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:
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
Please see the documentation for talloc_set_log_fn() and talloc_set_log_stderr() for more information on talloc logging functions.
If TALLOC_FREE_FILL
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.
[in] | ptr | The chunk to be freed. |
Example:
unsigned int *a, *b; a = talloc(NULL, unsigned int); b = talloc(a, unsigned int); talloc_free(a); // Frees a and b
void talloc_free_children | ( | void * | ptr | ) |
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.
[in] | ptr | The chunk that you want to free the children of (NULL is allowed too) |
const char* talloc_get_name | ( | const void * | ptr | ) |
Return the name of a talloc chunk.
[in] | ptr | The talloc chunk. |
type* talloc_get_type | ( | const void * | ptr, | |
# | type | |||
) |
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:
(type *)talloc_check_name(ptr, #type)
[in] | ptr | The talloc pointer to check. |
[in] | type | The type to check against. |
void* talloc_get_type_abort | ( | const void * | ptr, | |
# | type | |||
) |
Safely turn a void pointer into a typed pointer.
This macro is used together with talloc(mem_ctx, struct foo). If you had to assing 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.
[in] | ptr | The void pointer to convert. |
[in] | type | The type that this chunk contains |
void* talloc_init | ( | const char * | fmt, | |
... | ||||
) |
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:
talloc_named(NULL, 0, fmt, ...);
[in] | fmt | Format string for the name. |
[in] | ... | Additional printf-style arguments. |
void* talloc_memdup | ( | const void * | t, | |
const void * | p, | |||
size_t | size | |||
) |
Duplicate a memory area into a talloc chunk.
The function is equivalent to:
ptr = talloc_size(ctx, size); if (ptr) memcpy(ptr, p, size);
[in] | t | The talloc context to hang the result off. |
[in] | p | The memory chunk you want to duplicate. |
[in] | size | Number of char's that you want copy. |
void* talloc_move | ( | const void * | new_ctx, | |
void ** | pptr | |||
) |
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:
struct foo *X = talloc(tmp_ctx, struct foo); struct foo *Y; Y = talloc_move(new_ctx, &X);
[in] | new_ctx | The new parent context. |
[in] | pptr | Pointer to the talloc chunk to move. |
void* talloc_named | ( | const void * | context, | |
size_t | size, | |||
const char * | fmt, | |||
... | ||||
) |
Create a named talloc chunk.
The talloc_named() function creates a named talloc pointer. It is equivalent to:
ptr = talloc_size(context, size); talloc_set_name(ptr, fmt, ....);
[in] | context | The talloc context to hang the result off. |
[in] | size | Number of char's that you want to allocate. |
[in] | fmt | Format string for the name. |
[in] | ... | Additional printf-style arguments. |
void* talloc_named_const | ( | const void * | context, | |
size_t | size, | |||
const char * | name | |||
) |
Basic routine to allocate a chunk of memory.
This is equivalent to:
ptr = talloc_size(context, size); talloc_set_name_const(ptr, name);
[in] | context | The parent context. |
[in] | size | The number of char's that we want to allocate. |
[in] | name | The name the talloc block has. |
void* talloc_new | ( | const void * | ctx | ) |
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.
[in] | ctx | The talloc parent context. |
void* talloc_parent | ( | const void * | ptr | ) |
Get the parent chunk of a pointer.
[in] | ptr | The talloc pointer to inspect. |
const char* talloc_parent_name | ( | const void * | ptr | ) |
Get a talloc chunk's parent name.
[in] | ptr | The talloc pointer to inspect. |
void* talloc_pool | ( | const void * | context, | |
size_t | size | |||
) |
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.
[in] | context | The talloc context to hang the result off. |
[in] | size | Size of the talloc pool. |
void* talloc_pooled_object | ( | const void * | ctx, | |
# | type, | |||
unsigned | num_subobjects, | |||
size_t | total_subobjects_size | |||
) |
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.
[in] | ctx | The talloc context to hang the result off. |
[in] | type | The type that we want to allocate. |
[in] | num_subobjects | The expected number of subobjects, which will be allocated within the pool. This allocates space for talloc_chunk headers. |
[in] | total_subobjects_size | The size that all subobjects can use in total. |
void* talloc_ptrtype | ( | const void * | ctx, | |
# | type | |||
) |
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.
[in] | ctx | The talloc context to hang the result off. |
[in] | type | The pointer you want to assign the result to. |
Example:
unsigned int *a = talloc_ptrtype(NULL, a);
void talloc_set_destructor | ( | const void * | ptr, | |
int(*)(void *) | destructor | |||
) |
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.
[in] | ptr | The talloc chunk to add a destructor to. |
[in] | destructor | The destructor function to be called. NULL to remove it. |
Example:
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; }
const char* talloc_set_name | ( | const void * | ptr, | |
const char * | fmt, | |||
... | ||||
) |
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:
talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...));
[in] | ptr | The talloc chunk to assign a name to. |
[in] | fmt | Format string for the name. |
[in] | ... | Add printf-style additional arguments. |
void talloc_set_name_const | ( | const void * | ptr, | |
const char * | name | |||
) |
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().
[in] | ptr | The talloc chunk to assign a name to. |
[in] | name | Format string for the name. |
void talloc_set_type | ( | const char * | ptr, | |
# | type | |||
) |
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:
talloc_set_name_const(ptr, #type)
[in] | ptr | The talloc chunk to assign the type to. |
[in] | type | The type to assign. |
void* talloc_size | ( | const void * | ctx, | |
size_t | size | |||
) |
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.
[in] | ctx | The talloc context to hang the result off. |
[in] | size | Number of char's that you want to allocate. |
Example:
void *mem = talloc_size(NULL, 100);
void* talloc_steal | ( | const void * | new_ctx, | |
const void * | ptr | |||
) |
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:
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
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.
[in] | new_ctx | The new parent context. |
[in] | ptr | The talloc chunk to move. |
size_t talloc_total_blocks | ( | const void * | ptr | ) |
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.
[in] | ptr | The talloc chunk. |
size_t talloc_total_size | ( | const void * | ptr | ) |
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.
[in] | ptr | The talloc chunk. |
void* talloc_zero | ( | const void * | ctx, | |
# | type | |||
) |
Allocate a 0-initizialized structure.
The macro is equivalent to:
ptr = talloc(ctx, type); if (ptr) memset(ptr, 0, sizeof(type));
[in] | ctx | The talloc context to hang the result off. |
[in] | type | The type that we want to allocate. |
Example:
unsigned int *a, *b; a = talloc_zero(NULL, unsigned int); b = talloc_zero(a, unsigned int);
void* talloc_zero_size | ( | const void * | ctx, | |
size_t | size | |||
) |
Allocate untyped, 0-initialized memory.
[in] | ctx | The talloc context to hang the result off. |
[in] | size | Number of char's that you want to allocate. |