summaryrefslogtreecommitdiff
path: root/lib/tevent
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2014-07-22 13:08:42 +0200
committerRalph Boehme <slow@samba.org>2018-07-11 23:04:20 +0200
commit6740718e0e7db82563870ff398de90dac8f09228 (patch)
tree976117d616951499186241af7056be1d82487045 /lib/tevent
parenta85ee852accd9137dbffa1e41df8618123b00450 (diff)
downloadsamba-6740718e0e7db82563870ff398de90dac8f09228.tar.gz
tevent: split out tevent_common_invoke_immediate_handler()
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>
Diffstat (limited to 'lib/tevent')
-rw-r--r--lib/tevent/ABI/tevent-0.9.36.sigs1
-rw-r--r--lib/tevent/tevent_immediate.c87
-rw-r--r--lib/tevent/tevent_internal.h4
-rw-r--r--lib/tevent/tevent_threads.c6
4 files changed, 75 insertions, 23 deletions
diff --git a/lib/tevent/ABI/tevent-0.9.36.sigs b/lib/tevent/ABI/tevent-0.9.36.sigs
index bb89cc72d1e..451e380688c 100644
--- a/lib/tevent/ABI/tevent-0.9.36.sigs
+++ b/lib/tevent/ABI/tevent-0.9.36.sigs
@@ -32,6 +32,7 @@ tevent_common_fd_get_flags: uint16_t (struct tevent_fd *)
tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t)
tevent_common_have_events: bool (struct tevent_context *)
+tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *)
tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *)
tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *)
tevent_common_loop_immediate: bool (struct tevent_context *)
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index c640a565b08..0649d1eacf2 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -31,6 +31,12 @@
static void tevent_common_immediate_cancel(struct tevent_immediate *im)
{
const char *create_location = im->create_location;
+ bool busy = im->busy;
+
+ if (im->destroyed) {
+ tevent_abort(im->event_ctx, "tevent_immediate use after free");
+ return;
+ }
if (!im->event_ctx) {
return;
@@ -51,9 +57,12 @@ static void tevent_common_immediate_cancel(struct tevent_immediate *im)
*im = (struct tevent_immediate) {
.create_location = create_location,
+ .busy = busy,
};
- talloc_set_destructor(im, NULL);
+ if (!busy) {
+ talloc_set_destructor(im, NULL);
+ }
}
/*
@@ -61,7 +70,21 @@ static void tevent_common_immediate_cancel(struct tevent_immediate *im)
*/
static int tevent_common_immediate_destructor(struct tevent_immediate *im)
{
+ if (im->destroyed) {
+ tevent_common_check_double_free(im,
+ "tevent_immediate double free");
+ goto done;
+ }
+
tevent_common_immediate_cancel(im);
+
+ im->destroyed = true;
+
+done:
+ if (im->busy) {
+ return -1;
+ }
+
return 0;
}
@@ -76,6 +99,7 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
const char *location)
{
const char *create_location = im->create_location;
+ bool busy = im->busy;
tevent_common_immediate_cancel(im);
@@ -90,6 +114,7 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
.handler_name = handler_name,
.create_location = create_location,
.schedule_location = location,
+ .busy = busy,
};
DLIST_ADD_END(ev->immediate_events, im);
@@ -100,18 +125,14 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
handler_name, im);
}
-/*
- trigger the first immediate event and return true
- if no event was triggered return false
-*/
-bool tevent_common_loop_immediate(struct tevent_context *ev)
+int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
+ bool *removed)
{
- struct tevent_immediate *im = ev->immediate_events;
- tevent_immediate_handler_t handler;
- void *private_data;
+ struct tevent_context *ev = im->event_ctx;
+ struct tevent_immediate cur = *im;
- if (!im) {
- return false;
+ if (removed != NULL) {
+ *removed = false;
}
tevent_debug(ev, TEVENT_DEBUG_TRACE,
@@ -122,21 +143,41 @@ bool tevent_common_loop_immediate(struct tevent_context *ev)
* remember the handler and then clear the event
* the handler might reschedule the event
*/
- handler = im->handler;
- private_data = im->private_data;
- DLIST_REMOVE(im->event_ctx->immediate_events, im);
- im->event_ctx = NULL;
- im->handler = NULL;
- im->private_data = NULL;
- im->handler_name = NULL;
- im->schedule_location = NULL;
- im->cancel_fn = NULL;
- im->additional_data = NULL;
+ im->busy = true;
+ im->handler_name = NULL;
+ tevent_common_immediate_cancel(im);
+ cur.handler(ev, im, cur.private_data);
+ im->busy = false;
+
+ if (im->destroyed) {
+ talloc_set_destructor(im, NULL);
+ TALLOC_FREE(im);
+ if (removed != NULL) {
+ *removed = true;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ trigger the first immediate event and return true
+ if no event was triggered return false
+*/
+bool tevent_common_loop_immediate(struct tevent_context *ev)
+{
+ struct tevent_immediate *im = ev->immediate_events;
+ int ret;
- talloc_set_destructor(im, NULL);
+ if (!im) {
+ return false;
+ }
- handler(ev, im, private_data);
+ ret = tevent_common_invoke_immediate_handler(im, NULL);
+ if (ret != 0) {
+ tevent_abort(ev, "tevent_common_invoke_immediate_handler() failed");
+ }
return true;
}
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 8126414d683..d74684c72c2 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -203,6 +203,8 @@ struct tevent_timer {
struct tevent_immediate {
struct tevent_immediate *prev, *next;
struct tevent_context *event_ctx;
+ bool busy;
+ bool destroyed;
tevent_immediate_handler_t handler;
/* this is private for the specific handler */
void *private_data;
@@ -367,6 +369,8 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
void *private_data,
const char *handler_name,
const char *location);
+int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
+ bool *removed);
bool tevent_common_loop_immediate(struct tevent_context *ev);
void tevent_common_threaded_activate_immediate(struct tevent_context *ev);
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index efdac9856dd..9410765266e 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -482,6 +482,12 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
if ((im->event_ctx != NULL) || (handler == NULL)) {
abort();
}
+ if (im->destroyed) {
+ abort();
+ }
+ if (im->busy) {
+ abort();
+ }
*im = (struct tevent_immediate) {
.event_ctx = ev,