From 302013382b8040da359758c5842f888d3351e6eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 23 Jul 2009 10:05:41 +0200 Subject: [PATCH] talloc: add talloc_set_strict_owner_mode() metze --- lib/talloc/talloc.c | 25 +++++++++++++++++++++---- lib/talloc/talloc.h | 3 +++ lib/talloc/testsuite.c | 1 + 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index f68b1eb5ece5..6913c0885160 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -106,6 +106,7 @@ static void *null_context; static void *autofree_context; static void *no_owner_context = TALLOC_MAGIC_NO_OWNER; +static const char *strict_owner_mode; static inline int _talloc_free(void *ptr); struct talloc_reference_handle { @@ -142,6 +143,11 @@ struct talloc_chunk { #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) +void _talloc_set_strict_owner_mode(const char *location) +{ + strict_owner_mode = location; +} + static void (*talloc_abort_fn)(const char *reason); void talloc_set_abort_fn(void (*abort_fn)(const char *reason)) @@ -613,6 +619,15 @@ static inline int _talloc_free(void *ptr) if (is_child) { _talloc_free(tc->refs); return _talloc_free(ptr); + } else if (talloc_parent_is_no_owner(ptr)) { + /* + * if no_owner_context is already the owner + * we free the last reference (first in the list) + * + * This path is ownly reached if + * talloc_set_strict_owner_mode() wasn't used + */ + return _talloc_free(tc->refs); } else { /* * we can't free if we have refs, @@ -687,10 +702,11 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) return NULL; } - if (unlikely(talloc_parent_is_no_owner(ptr) && + if (unlikely(strict_owner_mode && + talloc_parent_is_no_owner(ptr) && new_ctx != no_owner_context)) { -// talloc_abort_no_owner_free(); -// return NULL; + talloc_abort_no_owner_free(); + return NULL; } if (unlikely(new_ctx == TALLOC_MAGIC_NO_OWNER)) { @@ -1029,7 +1045,8 @@ int talloc_free(void *ptr) return 0; } - if (unlikely(talloc_parent_is_no_owner(ptr))) { + if (unlikely(strict_owner_mode && + talloc_parent_is_no_owner(ptr))) { talloc_abort_no_owner_free(); return -1; } diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index a4b33c3ed4ab..30dc9b7eb41c 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -187,4 +187,7 @@ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIB void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); +#define talloc_set_strict_owner_mode() _talloc_set_strict_owner_mode(__location__) +void _talloc_set_strict_owner_mode(const char *location); + #endif diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c index 8720f0dbff21..b46a024dffe2 100644 --- a/lib/talloc/testsuite.c +++ b/lib/talloc/testsuite.c @@ -1523,6 +1523,7 @@ static void test_reset(void) test_abort_stop(); talloc_disable_null_tracking(); talloc_enable_null_tracking(); + talloc_set_strict_owner_mode(); } struct torture_context; -- 2.34.1