diff options
author | Stefan Metzmacher <metze@samba.org> | 2014-07-22 14:45:33 +0200 |
---|---|---|
committer | Ralph Boehme <slow@samba.org> | 2018-07-11 23:04:21 +0200 |
commit | 072e3b28ce029dd103ef2ea9836b6c6254825a8e (patch) | |
tree | 06c9a226d0729461cb3000dd47f544865cc18707 | |
parent | 6740718e0e7db82563870ff398de90dac8f09228 (diff) | |
download | samba-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>
-rw-r--r-- | lib/tevent/ABI/tevent-0.9.36.sigs | 1 | ||||
-rw-r--r-- | lib/tevent/tevent_epoll.c | 3 | ||||
-rw-r--r-- | lib/tevent/tevent_fd.c | 39 | ||||
-rw-r--r-- | lib/tevent/tevent_internal.h | 4 | ||||
-rw-r--r-- | lib/tevent/tevent_poll.c | 3 | ||||
-rw-r--r-- | lib/tevent/tevent_port.c | 3 |
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); } } |