[PATCH 1/3] Make explicit free behave the same as implicit free

Sam Liddicott sam at liddicott.com
Thu Jan 15 14:00:43 GMT 2009


[I missed some of this in the previous post, sorry]

If a referenced allocation is explicitly freed the new owner
should be the same as if the same allocation is implicitly freed
(e.g. because it's owner was freed).

Previously in talloc an explicit free will remove the top non-child
reference
but an implicit free will move the top (any) reference to be the new owner
---
 lib/talloc/testsuite.c |   66
++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c
index 3d490dd..c56cef4 100644
--- a/lib/talloc/testsuite.c
+++ b/lib/talloc/testsuite.c
@@ -784,6 +784,71 @@ static bool test_unref_reparent(void)
 	return true;
 }

+/* If a referenced allocation is explicitly freed the new owner
+   should be the same as if the same allocation is implicitly freed
+   (because it's owner was freed).
+   Traditionally in talloc an explicit free will free the top non-child
reference
+   but an implicit free will move the top (any) reference to be the new
owner */
+static bool test_implicit_explicit_free(void)
+{
+	void *root, *p1, *p2, *p3, *ref, *r1;
+	int e, i;
+
+	printf("test: test_implicit_explicit_free\n# SINGLE REFERENCE IMPLICIT
FREE\n");
+
+	root = talloc_named_const(NULL, 0, "root");
+	p1 = talloc_named_const(root, 1, "p1");
+	p2 = talloc_named_const(p1, 1, "p2");
+	/* Now root owns p1, and p1 owns p2 */
+
+	r1 = talloc_named_const(root, 1, "r1");
+	ref = talloc_reference(r1, p2);
+	/* now r1 has ref reference to p2 */
+	talloc_report_full(root, stderr);
+
+	CHECK_BLOCKS(__FUNCTION__, p1, 2);
+	CHECK_BLOCKS(__FUNCTION__, p2, 1);
+	CHECK_BLOCKS(__FUNCTION__, r1, 2);
+
+	fprintf(stderr, "Freeing p2\n");
+	talloc_free(p2);
+	/* how many blocks is r1 taking against p2 ? */
+	e=talloc_total_blocks(r1);
+
+	talloc_report_full(root, stderr);
+	talloc_free(root);
+
+	/* now repeat, but this time free p1 */
+	printf("test: test_implicit_explicit_free\n# SINGLE REFERENCE EXPLICIT
FREE\n");
+
+	root = talloc_named_const(NULL, 0, "root");
+	p1 = talloc_named_const(root, 1, "p1");
+	p2 = talloc_named_const(p1, 1, "p2");
+	/* Now root owns p1, and p1 owns p2 */
+
+	r1 = talloc_named_const(root, 1, "r1");
+	ref = talloc_reference(r1, p2);
+	/* now r1 has ref reference to p2 */
+	talloc_report_full(NULL, stderr);
+
+	CHECK_BLOCKS(__FUNCTION__, p1, 2);
+	CHECK_BLOCKS(__FUNCTION__, p2, 1);
+	CHECK_BLOCKS(__FUNCTION__, r1, 2);
+
+	fprintf(stderr, "Freeing p1\n");
+	talloc_free(p1);
+	/* how many blocks is r1 taking against p2 ? */
+	i=talloc_total_blocks(r1);
+	talloc_report_full(NULL, stderr);
+
+	CHECK_BLOCKS(__FUNCTION__,r1, e);
+
+	talloc_free(root);
+
+	printf("success: ref1\n");
+	return true;
+}
+
 /*
   measure the speed of talloc versus malloc
 */
@@ -1132,6 +1197,7 @@ bool torture_local_talloc(struct torture_context
*tctx)
 	ret &= test_talloc_ptrtype();
 	ret &= test_talloc_free_in_destructor();
 	ret &= test_pool();
+	ret &= test_implicit_explicit_free();

 	if (ret) {
 		ret &= test_speed();


More information about the samba-technical mailing list