From: Stefan Metzmacher Date: Wed, 15 Jul 2009 10:08:03 +0000 (+0200) Subject: TODO: more talloc no_owner fixes fixes X-Git-Url: http://git.samba.org/?a=commitdiff_plain;ds=sidebyside;h=2ced1ddd13af2fa3f51c73e78c4f7050ea122d72;p=metze%2Fsamba%2Fwip.git TODO: more talloc no_owner fixes fixes --- diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 4ed48fe59dcb..f68b1eb5ece5 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -64,6 +64,7 @@ #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ #define TALLOC_MAGIC_REFERENCE ((const char *)1) #define TALLOC_MAGIC_NO_OWNER ((void *)1) +#define TALLOC_MAGIC_NO_OWNER_TC ((struct talloc_chunk *)1) /* by default we abort when given a bad pointer (such as when talloc_free() is called on a pointer that came from malloc() */ @@ -216,10 +217,10 @@ do { \ if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ } while (0) -static inline talloc_parent_is_no_owner(const void *ptr) +static inline bool talloc_parent_is_no_owner(const void *ptr) { struct talloc_chunk *tc; - struct talloc_chunk *no_owner_tc = TALLOC_MAGIC_NO_OWNER; + struct talloc_chunk *no_owner_tc = TALLOC_MAGIC_NO_OWNER_TC; tc = talloc_chunk_from_ptr(ptr); @@ -234,6 +235,9 @@ static inline talloc_parent_is_no_owner(const void *ptr) return false; } +#define TALLOC_INVALID_PARENT(tc) \ + ((((tc)->parent == NULL)||((tc)->parent == TALLOC_MAGIC_NO_OWNER_TC))) + /* return the parent chunk of a pointer */ @@ -248,7 +252,7 @@ static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) tc = talloc_chunk_from_ptr(ptr); while (tc->prev) tc=tc->prev; - if (unlikely(tc->parent == TALLOC_MAGIC_NO_OWNER)) { + if (unlikely(TALLOC_INVALID_PARENT(tc))) { return NULL; } @@ -270,6 +274,20 @@ const char *talloc_parent_name(const void *ptr) return tc? tc->name : NULL; } +static inline void talloc_remove_from_parent(struct talloc_chunk *tc) +{ + if (!TALLOC_INVALID_PARENT(tc)) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } +// tc->parent = tc->prec = tc->next = NULL; +} + /* A pool carries an in-pool object count count in the first 16 bytes. bytes. This is done to support talloc_steal() to a parent outside of the @@ -623,15 +641,7 @@ static inline int _talloc_free(void *ptr) tc->destructor = NULL; } - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } + talloc_remove_from_parent(tc); _talloc_free_children(tc); @@ -671,6 +681,7 @@ static inline int _talloc_free(void *ptr) void *_talloc_steal(const void *new_ctx, const void *ptr) { struct talloc_chunk *tc, *new_tc; + bool no_owner_null = false; if (unlikely(!ptr)) { return NULL; @@ -678,11 +689,12 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) if (unlikely(talloc_parent_is_no_owner(ptr) && new_ctx != no_owner_context)) { - talloc_abort_no_owner_free(); - return NULL; +// talloc_abort_no_owner_free(); +// return NULL; } if (unlikely(new_ctx == TALLOC_MAGIC_NO_OWNER)) { + no_owner_null = true; new_ctx = NULL; } @@ -693,17 +705,12 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) tc = talloc_chunk_from_ptr(ptr); if (unlikely(new_ctx == NULL)) { - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - + talloc_remove_from_parent(tc); + tc->parent = tc->next = tc->prev = NULL; + if (unlikely(no_owner_null)) { + tc->parent = TALLOC_MAGIC_NO_OWNER_TC; + } return discard_const_p(void, ptr); } @@ -713,15 +720,7 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) return discard_const_p(void, ptr); } - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } + talloc_remove_from_parent(tc); tc->parent = new_tc; if (new_tc->child) new_tc->child->parent = NULL; @@ -767,8 +766,7 @@ static inline int talloc_unreference(const void *context, const void *ptr) */ int talloc_unlink(const void *context, void *ptr) { - struct talloc_chunk *tc_p, *new_p; - void *new_parent; + struct talloc_chunk *tc_p; if (ptr == NULL) { return -1; @@ -1123,7 +1121,7 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n if (malloced) { tc->flags &= ~TALLOC_FLAG_POOLMEM; } - if (tc->parent) { + if (!TALLOC_INVALID_PARENT(tc)) { tc->parent->child = tc; } if (tc->child) { @@ -1822,6 +1820,9 @@ void *talloc_find_parent_byname(const void *context, const char *name) } while (tc && tc->prev) tc = tc->prev; if (tc) { + if (TALLOC_INVALID_PARENT(tc)) { + break; + } tc = tc->parent; } } @@ -1846,6 +1847,10 @@ void talloc_show_parents(const void *context, FILE *file) fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); while (tc && tc->prev) tc = tc->prev; if (tc) { + if (tc->parent == TALLOC_MAGIC_NO_OWNER_TC) { + fprintf(file, "\t'no_owner_context'\n"); + break; + } tc = tc->parent; } } @@ -1868,6 +1873,9 @@ int talloc_is_parent(const void *context, const void *ptr) if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; while (tc && tc->prev) tc = tc->prev; if (tc) { + if (TALLOC_INVALID_PARENT(tc)) { + break; + } tc = tc->parent; } }