talloc: add talloc_set_strict_owner_mode()
authorStefan Metzmacher <metze@samba.org>
Thu, 23 Jul 2009 08:05:41 +0000 (10:05 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 23 Jul 2009 08:05:41 +0000 (10:05 +0200)
metze

lib/talloc/talloc.c
lib/talloc/talloc.h
lib/talloc/testsuite.c

index f68b1eb5ece523583be18c44609959e6d7c5a7c4..6913c088516056da2df12df6d2d1b74e1800ab12 100644 (file)
 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;
        }
index a4b33c3ed4ab5ab317f0b297a8d1e866592ce25c..30dc9b7eb41c6f753a423da82d4db5da5c232e6c 100644 (file)
@@ -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
index 8720f0dbff21d8ebfab0d0a3625a31456428757f..b46a024dffe2c2034d3af01b07b0b8698ff4943d 100644 (file)
@@ -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;