static void *null_context;
static void *autofree_context;
static void *no_owner_context = TALLOC_MAGIC_NO_OWNER;
+static const char *strict_owner_mode;
static inline int _talloc_free(void *ptr);
struct talloc_reference_handle {
#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
+void _talloc_set_strict_owner_mode(const char *location)
+{
+ strict_owner_mode = location;
+}
+
static void (*talloc_abort_fn)(const char *reason);
void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
if (is_child) {
_talloc_free(tc->refs);
return _talloc_free(ptr);
+ } else if (talloc_parent_is_no_owner(ptr)) {
+ /*
+ * if no_owner_context is already the owner
+ * we free the last reference (first in the list)
+ *
+ * This path is ownly reached if
+ * talloc_set_strict_owner_mode() wasn't used
+ */
+ return _talloc_free(tc->refs);
} else {
/*
* we can't free if we have refs,
return NULL;
}
- if (unlikely(talloc_parent_is_no_owner(ptr) &&
+ if (unlikely(strict_owner_mode &&
+ 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)) {
return 0;
}
- if (unlikely(talloc_parent_is_no_owner(ptr))) {
+ if (unlikely(strict_owner_mode &&
+ talloc_parent_is_no_owner(ptr))) {
talloc_abort_no_owner_free();
return -1;
}