From: Sam Liddicott Date: Mon, 2 Feb 2009 12:12:08 +0000 (+0000) Subject: talloc testsuite: test (ref, free, steal) destroys reference X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=1672a0cc1e2751d6665854fd59baeb6661138534 talloc testsuite: test (ref, free, steal) destroys reference ref, free, steal destroys the reference (as it became the new owner on free) and stops the reference from keeping the object alive. references should only be removed by permission of the reference owner. Current behaviour may be according to design, but it's very awkward. Signed-off-by: Sam Liddicott --- diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c index 5c720cb42752..65742f2194f5 100644 --- a/lib/talloc/testsuite.c +++ b/lib/talloc/testsuite.c @@ -1125,6 +1125,66 @@ static bool test_dangling_loop(void) return true; } +/* If take r1 reference to p2 and then free p2's owner p1 + p2 should still be around by virtue of the reference. + steal p2 to p3 and free p3. + In current talloc p2 will be freed despite the reference. + In proposed talloc r1 will be the reference with no parent for p2*/ +static bool test_ref_free_steal(void) +{ + void *root, *p1, *p2, *p3, *ref, *r1; + + printf("test: ref_free_self\n# SINGLE REFERENCE FREE SELF FREE\n"); + talloc_erase_no_owner_context(); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + p2 = talloc_named_const(p1, 1, "p2"); + p3 = talloc_named_const(root, 1, "p3"); + /* 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__, p3, 1); + CHECK_BLOCKS(__FUNCTION__, r1, 2); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + /* r1 should have ref reference to p2 still */ + talloc_report_full(NULL, stderr); + CHECK_BLOCKS(__FUNCTION__, r1, 2); + + /* if we talloc_steal p2 to p3, r1 should still have a reference + (unless it had been made the parent like in old talloc */ + fprintf(stderr, "Steal p2 to p3\n"); + talloc_steal(p3, p2); + talloc_report_full(NULL, stderr); + //CHECK_BLOCKS(__FUNCTION__, r1, 2); + + /* now we free p3 and r1 should still have a reference */ + fprintf(stderr, "free p3\n"); + talloc_free(p3); + talloc_report_full(NULL, stderr); + CHECK_BLOCKS(__FUNCTION__, p2, 1); + CHECK_BLOCKS(__FUNCTION__, r1, 2); + + /* if we free r1 then p2 should also vanish */ + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + + talloc_report_full(NULL, stderr); + CHECK_BLOCKS(__FUNCTION__, root, 1); + + talloc_free(root); + printf("success: ref1\n"); + return true; +} + /* measure the speed of talloc versus malloc */ @@ -1495,6 +1555,7 @@ bool torture_local_talloc(struct torture_context *tctx) ret &= test_talloc_free_in_destructor(); ret &= test_implicit_explicit_free(); ret &= test_dangling_loop(); + ret &= test_ref_free_steal(); ret &= test_ref_free_owner(); ret &= test_ref_free_self(); ret &= test_ref_free();