summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-04-17 16:33:47 +0200
committerRalph Boehme <slow@samba.org>2018-07-11 23:04:19 +0200
commit58fa08c80562490bd774f4dc774dc1ce3a042f3c (patch)
tree40fd831c11947cc3a92a17dd29605943e83d57fb
parent157df4da26aeb46eedf1a0f3895cc5fbc751f1dc (diff)
downloadsamba-58fa08c80562490bd774f4dc774dc1ce3a042f3c.tar.gz
tevent: add tevent_common_check_double_free() helper function
This will be used to generically support TALLOC_FREE() on event which are currently running. It aborts on every explicit talloc_free(), but ignores implicit cleanup when the talloc parent is about to go. We'll undo the 0.9.36 ABI change on the 0.9.37 release at the end of this patchset. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
-rw-r--r--lib/tevent/ABI/tevent-0.9.36.sigs1
-rw-r--r--lib/tevent/tevent.c19
-rw-r--r--lib/tevent/tevent_internal.h2
3 files changed, 22 insertions, 0 deletions
diff --git a/lib/tevent/ABI/tevent-0.9.36.sigs b/lib/tevent/ABI/tevent-0.9.36.sigs
index 07d6e29fddd..8a9d1a6ba10 100644
--- a/lib/tevent/ABI/tevent-0.9.36.sigs
+++ b/lib/tevent/ABI/tevent-0.9.36.sigs
@@ -24,6 +24,7 @@ tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *,
tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_check_double_free: void (TALLOC_CTX *, const char *)
tevent_common_check_signal: int (struct tevent_context *)
tevent_common_context_destructor: int (struct tevent_context *)
tevent_common_fd_destructor: int (struct tevent_fd *)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 222a3a1a3dd..de0436df373 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -429,6 +429,25 @@ static int tevent_common_context_constructor(struct tevent_context *ev)
return 0;
}
+void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason)
+{
+ void *parent_ptr = talloc_parent(ptr);
+ size_t parent_blocks = talloc_total_blocks(parent_ptr);
+
+ if (parent_ptr != NULL && parent_blocks == 0) {
+ /*
+ * This is an implicit talloc free, as we still have a parent
+ * but it's already being destroyed. Note that
+ * talloc_total_blocks(ptr) also just returns 0 if a
+ * talloc_free(ptr) is still in progress of freeing all
+ * children.
+ */
+ return;
+ }
+
+ tevent_abort(NULL, reason);
+}
+
/*
create a event_context structure for a specific implemementation.
This must be the first events call, and all subsequent calls pass
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index b13efedb5d9..7e15a59d3fb 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -248,6 +248,8 @@ void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
void tevent_abort(struct tevent_context *ev, const char *reason);
+void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason);
+
struct tevent_context {
/* the specific events implementation */
const struct tevent_ops *ops;