r3553: Allow talloc_reference to take a NULL pointer for the "ptr" argument.
authorAndrew Bartlett <abartlet@samba.org>
Fri, 5 Nov 2004 12:20:27 +0000 (12:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:05:31 +0000 (13:05 -0500)
This allows potentially NULL pointers to be referenced, without an if ()
for every use.  (previously, it would segfault).

Update doco, and allow talloc_unlink to match.

Andrew Bartlett

source/lib/talloc.c
source/torture/local/talloc.c
talloc_guide.txt

index 131edfcb817170fa5d6e39023e03f9464b34bd55..239958258bbed688ee5198a01f7bb87cb687c66a 100644 (file)
@@ -222,9 +222,13 @@ static int talloc_reference_destructor(void *ptr)
 */
 void *talloc_reference(const void *context, const void *ptr)
 {
 */
 void *talloc_reference(const void *context, const void *ptr)
 {
-       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       struct talloc_chunk *tc;
        struct talloc_reference_handle *handle;
        struct talloc_reference_handle *handle;
+       if (ptr == NULL) return NULL;
+
+       tc = talloc_chunk_from_ptr(ptr);
        handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
        handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
+
        if (handle == NULL) return NULL;
 
        /* note that we hang the destructor off the handle, not the
        if (handle == NULL) return NULL;
 
        /* note that we hang the destructor off the handle, not the
@@ -273,6 +277,10 @@ int talloc_unlink(const void *context, void *ptr)
        struct talloc_chunk *tc_p, *new_p;
        void *new_parent;
 
        struct talloc_chunk *tc_p, *new_p;
        void *new_parent;
 
+       if (ptr == NULL) {
+               return -1;
+       }
+
        if (context == NULL) {
                context = null_context;
        }
        if (context == NULL) {
                context = null_context;
        }
index 348b037753adb200557659ada5a38e5faf3f4366..2eedb2b9b08fea813d556aedceda2667b6cfd4d8 100644 (file)
@@ -117,6 +117,11 @@ static BOOL test_ref1(void)
        talloc_free(r1);
        talloc_report_full(NULL, stdout);
 
        talloc_free(r1);
        talloc_report_full(NULL, stdout);
 
+       printf("Testing NULL\n");
+       if (talloc_reference(root, NULL)) {
+               return False;
+       }
+
        CHECK_BLOCKS(root, 1);
 
        CHECK_SIZE(root, 0);
        CHECK_BLOCKS(root, 1);
 
        CHECK_SIZE(root, 0);
@@ -478,7 +483,12 @@ static BOOL test_misc(void)
        talloc_unlink(NULL, p2);
        talloc_unlink(root, p1);
 
        talloc_unlink(NULL, p2);
        talloc_unlink(root, p1);
 
-       
+       /* Test that talloc_unlink is a no-op */
+
+       if (talloc_unlink(root, NULL) != -1) {
+               printf("failed: talloc_unlink(root, NULL) == -1\n");
+               return False;
+       }
 
        talloc_report(root, stdout);
        talloc_report(NULL, stdout);
 
        talloc_report(root, stdout);
        talloc_report(NULL, stdout);
index a794cdffbe51cae1cf09a3773e553132cd627654..b3b148d4768b6d8adf619fee76ecaa313d8682e7 100644 (file)
@@ -122,6 +122,8 @@ The return value of talloc_reference() is always the original pointer
 which case it will return NULL (each additional reference consumes
 around 48 bytes of memory on intel x86 platforms).
 
 which case it will return NULL (each additional reference consumes
 around 48 bytes of memory on intel x86 platforms).
 
+If "ptr" is NULL, then the function is a no-op, and simply returns NULL.
+
 After creating a reference you can free it in one of the following
 ways:
 
 After creating a reference you can free it in one of the following
 ways:
 
@@ -144,7 +146,8 @@ context passed must either be a context used in talloc_reference()
 with this pointer, or must be a direct parent of ptr. 
 
 Note that if the parent has already been removed using talloc_free()
 with this pointer, or must be a direct parent of ptr. 
 
 Note that if the parent has already been removed using talloc_free()
-then this function will fail and will return -1.
+then this function will fail and will return -1.  Likewise, if "ptr"
+is NULL, then the function will make no modifications and return -1.
 
 Usually you can just use talloc_free() instead of talloc_unlink(), but
 sometimes it is useful to have the additional control on which parent
 
 Usually you can just use talloc_free() instead of talloc_unlink(), but
 sometimes it is useful to have the additional control on which parent