summaryrefslogtreecommitdiff
path: root/lib/tevent
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2014-07-22 14:45:33 +0200
committerRalph Boehme <slow@samba.org>2018-07-11 23:04:21 +0200
commit072e3b28ce029dd103ef2ea9836b6c6254825a8e (patch)
tree06c9a226d0729461cb3000dd47f544865cc18707 /lib/tevent
parent6740718e0e7db82563870ff398de90dac8f09228 (diff)
downloadsamba-072e3b28ce029dd103ef2ea9836b6c6254825a8e.tar.gz
tevent: split out tevent_common_invoke_fd_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_epoll.c3
-rw-r--r--lib/tevent/tevent_fd.c39
-rw-r--r--lib/tevent/tevent_internal.h4
-rw-r--r--lib/tevent/tevent_poll.c3
-rw-r--r--lib/tevent/tevent_port.c3
6 files changed, 47 insertions, 6 deletions
diff --git a/lib/tevent/ABI/tevent-0.9.36.sigs b/lib/tevent/ABI/tevent-0.9.36.sigs
index 451e380688c..443bb7cb6c9 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_fd_handler: int (struct tevent_fd *, uint16_t, bool *)
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 *)
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 4147c67af2a..5f7ef5d83d1 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -725,8 +725,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
*/
flags &= fde->flags;
if (flags) {
- fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
- break;
+ return tevent_common_invoke_fd_handler(fde, flags, NULL);
}
}
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
index f33ae841b39..7859cbb00ef 100644
--- a/lib/tevent/tevent_fd.c
+++ b/lib/tevent/tevent_fd.c
@@ -30,6 +30,12 @@
int tevent_common_fd_destructor(struct tevent_fd *fde)
{
+ if (fde->destroyed) {
+ tevent_common_check_double_free(fde, "tevent_fd double free");
+ goto done;
+ }
+ fde->destroyed = true;
+
if (fde->event_ctx) {
DLIST_REMOVE(fde->event_ctx->fd_events, fde);
}
@@ -37,6 +43,13 @@ int tevent_common_fd_destructor(struct tevent_fd *fde)
if (fde->close_fn) {
fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data);
fde->fd = -1;
+ fde->close_fn = NULL;
+ }
+
+ fde->event_ctx = NULL;
+done:
+ if (fde->busy) {
+ return -1;
}
return 0;
@@ -92,3 +105,29 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
{
fde->close_fn = close_fn;
}
+
+int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
+ bool *removed)
+{
+ if (removed != NULL) {
+ *removed = false;
+ }
+
+ if (fde->event_ctx == NULL) {
+ return 0;
+ }
+
+ fde->busy = true;
+ fde->handler(fde->event_ctx, fde, flags, fde->private_data);
+ fde->busy = false;
+
+ if (fde->destroyed) {
+ talloc_set_destructor(fde, NULL);
+ TALLOC_FREE(fde);
+ if (removed != NULL) {
+ *removed = true;
+ }
+ }
+
+ return 0;
+}
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index d74684c72c2..1183b9f7f83 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -170,6 +170,8 @@ struct tevent_req {
struct tevent_fd {
struct tevent_fd *prev, *next;
struct tevent_context *event_ctx;
+ bool busy;
+ bool destroyed;
int fd;
uint16_t flags; /* see TEVENT_FD_* flags */
tevent_fd_handler_t handler;
@@ -343,6 +345,8 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
tevent_fd_close_fn_t close_fn);
uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
+int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
+ bool *removed);
struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index 282f3cf3082..74c418ca421 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -565,8 +565,7 @@ static int poll_event_loop_poll(struct tevent_context *ev,
flags &= fde->flags;
if (flags != 0) {
DLIST_DEMOTE(ev->fd_events, fde);
- fde->handler(ev, fde, flags, fde->private_data);
- return 0;
+ return tevent_common_invoke_fd_handler(fde, flags, NULL);
}
}
diff --git a/lib/tevent/tevent_port.c b/lib/tevent/tevent_port.c
index 8cf9fd1a0de..e91d442389d 100644
--- a/lib/tevent/tevent_port.c
+++ b/lib/tevent/tevent_port.c
@@ -600,8 +600,7 @@ static int port_event_loop(struct port_event_context *port_ev, struct timeval *t
*/
flags &= fde->flags;
if (flags) {
- fde->handler(ev, fde, flags, fde->private_data);
- break;
+ return tevent_common_invoke_fd_handler(fde, flags, NULL);
}
}