From: Stefan Metzmacher Date: Thu, 23 Jul 2009 11:43:46 +0000 (+0200) Subject: more fixes X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=refs%2Fheads%2Fmaster4-talloc-sam more fixes --- diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 6913c0885160..e28d91fc68c5 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -280,7 +280,8 @@ const char *talloc_parent_name(const void *ptr) return tc? tc->name : NULL; } -static inline void talloc_remove_from_parent(struct talloc_chunk *tc) +static inline void talloc_remove_from_parent(struct talloc_chunk *tc, + bool reset_parent) { if (!TALLOC_INVALID_PARENT(tc)) { _TLIST_REMOVE(tc->parent->child, tc); @@ -291,7 +292,13 @@ static inline void talloc_remove_from_parent(struct talloc_chunk *tc) if (tc->prev) tc->prev->next = tc->next; if (tc->next) tc->next->prev = tc->prev; } -// tc->parent = tc->prec = tc->next = NULL; + tc->prev = tc->next = NULL; + /* + * Note: we only reset tc->parent = NULL when the caller asked for it + */ + if (reset_parent) { + tc->parent = NULL; + } } /* @@ -603,10 +610,6 @@ static inline int _talloc_free(void *ptr) tc = talloc_chunk_from_ptr(ptr); if (unlikely(tc->refs)) { - /*TODO: Fix this loop detection. The code here breaks top reference if - it is also one of our children. It is insufficient and can lead - to dangling references */ - int is_child; /* check this is a reference from a child or grantchild * back to it's parent or grantparent @@ -656,7 +659,13 @@ static inline int _talloc_free(void *ptr) tc->destructor = NULL; } - talloc_remove_from_parent(tc); + /* + * Note: we ask talloc_remove_from_parent() to keep + * tc->parent valid, because _talloc_free_children() + * needs it to find the parent for child where + * the destructor rejects the _talloc_free() + */ + talloc_remove_from_parent(tc, false); _talloc_free_children(tc); @@ -721,9 +730,8 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) tc = talloc_chunk_from_ptr(ptr); if (unlikely(new_ctx == NULL)) { - talloc_remove_from_parent(tc); + talloc_remove_from_parent(tc, true); - tc->parent = tc->next = tc->prev = NULL; if (unlikely(no_owner_null)) { tc->parent = TALLOC_MAGIC_NO_OWNER_TC; } @@ -736,7 +744,7 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) return discard_const_p(void, ptr); } - talloc_remove_from_parent(tc); + talloc_remove_from_parent(tc, true); tc->parent = new_tc; if (new_tc->child) new_tc->child->parent = NULL;