#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() */
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);
return false;
}
+#define TALLOC_INVALID_PARENT(tc) \
+ ((((tc)->parent == NULL)||((tc)->parent == TALLOC_MAGIC_NO_OWNER_TC)))
+
/*
return the parent chunk of a pointer
*/
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;
}
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
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);
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;
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;
}
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);
}
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;
*/
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;
if (malloced) {
tc->flags &= ~TALLOC_FLAG_POOLMEM;
}
- if (tc->parent) {
+ if (!TALLOC_INVALID_PARENT(tc)) {
tc->parent->child = tc;
}
if (tc->child) {
}
while (tc && tc->prev) tc = tc->prev;
if (tc) {
+ if (TALLOC_INVALID_PARENT(tc)) {
+ break;
+ }
tc = tc->parent;
}
}
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;
}
}
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;
}
}