svn commit: samba r2677 - in branches/SAMBA_4_0/source/lib: .

tridge at samba.org tridge at samba.org
Mon Sep 27 08:38:13 GMT 2004


Author: tridge
Date: 2004-09-27 08:38:13 +0000 (Mon, 27 Sep 2004)
New Revision: 2677

WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/branches/SAMBA_4_0/source/lib&rev=2677&nolog=1

Log:
- fixed a bug in the recursive logic talloc_free() when there are
  circular references (circular references are allowed, they just need
  to be handled carefully inside talloc)

- mark talloc_reference() pointers nicely in the --leak-report-full
  code, so you see what has a reference to what in a useful manner

Modified:
   branches/SAMBA_4_0/source/lib/talloc.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/talloc.c
===================================================================
--- branches/SAMBA_4_0/source/lib/talloc.c	2004-09-27 05:15:14 UTC (rev 2676)
+++ branches/SAMBA_4_0/source/lib/talloc.c	2004-09-27 08:38:13 UTC (rev 2677)
@@ -146,7 +146,7 @@
 void *talloc_reference(const void *context, const void *ptr)
 {
 	void **handle;
-	handle = _talloc(context, sizeof(void *));
+	handle = talloc_named_const(context, sizeof(void *), ".reference");
 	if (handle == NULL) {
 		return NULL;
 	}
@@ -169,6 +169,9 @@
 {
 	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
 	tc->name = talloc_vasprintf(ptr, fmt, ap);
+	if (tc->name) {
+		talloc_set_name_const(tc->name, ".name");
+	}
 }
 
 /*
@@ -267,7 +270,6 @@
 }
 
 
-
 /* 
    free a talloc pointer. This also frees all child pointers of this 
    pointer recursively
@@ -278,7 +280,7 @@
 */
 int talloc_free(void *ptr)
 {
-	struct talloc_chunk *tc;
+	struct talloc_chunk *tc, *tc2, *next;
 
 	if (ptr == NULL) {
 		return -1;
@@ -286,23 +288,26 @@
 
 	tc = talloc_chunk_from_ptr(ptr);
 
-	tc->ref_count--;
-	if (tc->ref_count != 0) {
+	if (tc->ref_count > 1) {
+		tc->ref_count--;
 		return -1;
 	}
 
-	if (tc->destructor && tc->destructor(ptr) == -1) {
-		tc->ref_count++;
-		return -1;
+	/* while processing the free, increase the reference count
+	   so we don't recurse into this function */
+	tc->ref_count++;
+	if (tc->destructor) {
+		if (tc->destructor(ptr) == -1) {
+			tc->ref_count--;
+			return -1;
+		}
 	}
 
-	while (tc->child) {
-		if (talloc_free(tc->child + 1) != 0) {
-			tc->child->parent = NULL;
-			break;
-		}
+	for (tc2=tc->child;tc2;tc2=next) {
+		next = tc2->next;
+		talloc_free(tc2 + 1);
 	}
-
+	
 	if (tc->parent) {
 		DLIST_REMOVE(tc->parent->child, tc);
 		if (tc->parent->child) {
@@ -313,6 +318,10 @@
 		if (tc->next) tc->next->prev = tc->prev;
 	}
 
+	if (tc->child) {
+		tc->child->parent = tc->parent;
+	}
+
 	tc->magic = TALLOC_MAGIC_FREE;
 
 	free(tc);
@@ -445,12 +454,20 @@
 	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
 
 	for (c=tc->child;c;c=c->next) {
-		fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks\n", 
-			depth*2, "",
-			talloc_get_name(c+1),
-			(unsigned long)talloc_total_size(c+1),
-			(unsigned long)talloc_total_blocks(c+1));
-		talloc_report_depth(c+1, f, depth+1);
+		const char *name = talloc_get_name(c+1);
+		if (strcmp(name, ".reference") == 0) {
+			void **handle = (void *)(c+1);
+			const char *name2 = talloc_get_name(*handle);
+			fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
+		} else {
+			fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 
+				depth*4, "",
+				name,
+				(unsigned long)talloc_total_size(c+1),
+				(unsigned long)talloc_total_blocks(c+1),
+				c->ref_count);
+			talloc_report_depth(c+1, f, depth+1);
+		}
 	}
 
 }
@@ -460,6 +477,11 @@
 */
 void talloc_report_full(const void *ptr, FILE *f)
 {
+	if (ptr == NULL) {
+		ptr = null_context;
+	}
+	if (ptr == NULL) return;
+
 	fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
 		talloc_get_name(ptr), 
 		(unsigned long)talloc_total_size(ptr),
@@ -473,13 +495,20 @@
 */
 void talloc_report(const void *ptr, FILE *f)
 {
-	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+	struct talloc_chunk *c, *tc;
 
+	if (ptr == NULL) {
+		ptr = null_context;
+	}
+	if (ptr == NULL) return;
+       
 	fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
 		talloc_get_name(ptr), 
 		(unsigned long)talloc_total_size(ptr),
 		(unsigned long)talloc_total_blocks(ptr));
 
+	tc = talloc_chunk_from_ptr(ptr);
+
 	for (c=tc->child;c;c=c->next) {
 		fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", 
 			talloc_get_name(c+1),



More information about the samba-cvs mailing list