From cf73dda652e0a121901f22771104be6751c0fcb9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 Jan 2005 12:55:33 +0000 Subject: [PATCH] r4479: added the function talloc_autofree_context() which returns a talloc context that will automatically be freed on program exit. This is useful for reducing clutter in leak reports --- source/lib/dcom/common/tables.c | 10 +++++++--- source/lib/registry/common/reg_interface.c | 2 +- source/lib/talloc/talloc.c | 21 +++++++++++++++++++++ source/lib/talloc/talloc.h | 1 + source/lib/talloc/talloc_guide.txt | 6 ++++++ source/librpc/rpc/dcerpc.c | 9 +++++---- 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/source/lib/dcom/common/tables.c b/source/lib/dcom/common/tables.c index 6b0d99cae3a..faf67710e08 100644 --- a/source/lib/dcom/common/tables.c +++ b/source/lib/dcom/common/tables.c @@ -76,10 +76,13 @@ const void *dcom_proxy_vtable_by_iid(const struct GUID *iid) NTSTATUS dcom_register_interface(const void *_iface) { const struct dcom_interface *iface = _iface; - struct interface_list *l = talloc_zero_p(interfaces, struct interface_list); + struct interface_list *l; + + l = talloc_zero_p(interfaces?interfaces:talloc_autofree_context(), + struct interface_list); l->interface = *iface; - + DLIST_ADD(interfaces, l); return NT_STATUS_OK; @@ -88,7 +91,8 @@ NTSTATUS dcom_register_interface(const void *_iface) NTSTATUS dcom_register_class(const void *_class) { const struct dcom_class *class = _class; - struct class_list *l = talloc_zero_p(classes, struct class_list); + struct class_list *l = talloc_zero_p(classes?classes:talloc_autofree_context(), + struct class_list); l->class = *class; diff --git a/source/lib/registry/common/reg_interface.c b/source/lib/registry/common/reg_interface.c index 9b03a69f3f8..442b34bc131 100644 --- a/source/lib/registry/common/reg_interface.c +++ b/source/lib/registry/common/reg_interface.c @@ -44,7 +44,7 @@ NTSTATUS registry_register(const void *_hive_ops) return NT_STATUS_OBJECT_NAME_COLLISION; } - entry = talloc_p(NULL, struct reg_init_function_entry); + entry = talloc_p(talloc_autofree_context(), struct reg_init_function_entry); entry->hive_functions = hive_ops; DLIST_ADD(backends, entry); diff --git a/source/lib/talloc/talloc.c b/source/lib/talloc/talloc.c index 4666e28288c..9e8868191fa 100644 --- a/source/lib/talloc/talloc.c +++ b/source/lib/talloc/talloc.c @@ -67,6 +67,7 @@ NULL */ static const void *null_context; +static void *cleanup_context; struct talloc_reference_handle { @@ -1004,3 +1005,23 @@ void *talloc_realloc_fn(const void *context, void *ptr, size_t size) { return _talloc_realloc(context, ptr, size, NULL); } + + +static void talloc_autofree(void) +{ + talloc_free(cleanup_context); + cleanup_context = NULL; +} + +/* + return a context which will be auto-freed on exit + this is useful for reducing the noise in leak reports +*/ +void *talloc_autofree_context(void) +{ + if (cleanup_context == NULL) { + cleanup_context = talloc_named_const(NULL, 0, "autofree_context"); + atexit(talloc_autofree); + } + return cleanup_context; +} diff --git a/source/lib/talloc/talloc.h b/source/lib/talloc/talloc.h index 6ebba447aad..9e828f2f0d6 100644 --- a/source/lib/talloc/talloc.h +++ b/source/lib/talloc/talloc.h @@ -91,6 +91,7 @@ void *talloc_array(const void *ctx, size_t el_size, unsigned count, const char * void *talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); void *talloc_realloc_fn(const void *context, void *ptr, size_t size); +void *talloc_autofree_context(void); #endif diff --git a/source/lib/talloc/talloc_guide.txt b/source/lib/talloc/talloc_guide.txt index b3b148d4768..ce3c8bde68f 100644 --- a/source/lib/talloc/talloc_guide.txt +++ b/source/lib/talloc/talloc_guide.txt @@ -490,3 +490,9 @@ implementation encapsulates the functionality of malloc(), free() and realloc() in one call, which is why it is useful to be able to pass around a single function pointer. +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_autofree_context(void); + +This is a handy utility function that returns a talloc context +which will be automatically freed on program exit. This can be used +to reduce the noise in memory leak reports. diff --git a/source/librpc/rpc/dcerpc.c b/source/librpc/rpc/dcerpc.c index f6c0ebc4132..e329297ab67 100644 --- a/source/librpc/rpc/dcerpc.c +++ b/source/librpc/rpc/dcerpc.c @@ -27,21 +27,22 @@ struct dcerpc_interface_list *dcerpc_pipes = NULL; -NTSTATUS librpc_register_interface (const struct dcerpc_interface_table *interface) +NTSTATUS librpc_register_interface(const struct dcerpc_interface_table *interface) { - struct dcerpc_interface_list *l = talloc_p(NULL, struct dcerpc_interface_list); + struct dcerpc_interface_list *l = talloc_p(talloc_autofree_context(), + struct dcerpc_interface_list); if (idl_iface_by_name (interface->name) != NULL) { DEBUG(0, ("Attempt to register interface %s twice\n", interface->name)); return NT_STATUS_OBJECT_NAME_COLLISION; } l->table = interface; - + DLIST_ADD(dcerpc_pipes, l); return NT_STATUS_OK; } - + /* initialise a dcerpc pipe. */ struct dcerpc_pipe *dcerpc_pipe_init(void) { -- 2.11.4.GIT