summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/talloc/talloc.c18
1 files changed, 3 insertions, 15 deletions
diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index a820ebf0ac..19e6a37f2c 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -838,6 +838,7 @@ static inline int _talloc_free_internal(void *ptr, const char *location)
} else {
if (tc->prev) tc->prev->next = tc->next;
if (tc->next) tc->next->prev = tc->prev;
+ tc->prev = tc->next = NULL;
}
tc->flags |= TALLOC_FLAG_LOOP;
@@ -925,6 +926,7 @@ static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
} else {
if (tc->prev) tc->prev->next = tc->next;
if (tc->next) tc->next->prev = tc->prev;
+ tc->prev = tc->next = NULL;
}
tc->parent = new_tc;
@@ -1251,23 +1253,9 @@ static inline void _talloc_free_children_internal(struct talloc_chunk *tc,
struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
if (p) new_parent = TC_PTR_FROM_CHUNK(p);
}
- /* finding the parent here is potentially quite
- expensive, but the alternative, which is to change
- talloc to always have a valid tc->parent pointer,
- makes realloc more expensive where there are a
- large number of children.
-
- The reason we need the parent pointer here is that
- if _talloc_free_internal() fails due to references
- or a failing destructor we need to re-parent, but
- the free call can invalidate the prev pointer.
- */
- if (new_parent == null_context && (tc->child->refs || tc->child->destructor)) {
- old_parent = talloc_parent_chunk(ptr);
- }
if (unlikely(_talloc_free_internal(child, location) == -1)) {
if (new_parent == null_context) {
- struct talloc_chunk *p = old_parent;
+ struct talloc_chunk *p = talloc_parent_chunk(ptr);
if (p) new_parent = TC_PTR_FROM_CHUNK(p);
}
_talloc_steal_internal(new_parent, child);