From ceac26008c6f36602259d0180f1e7f7a756ea4ad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 Jan 2009 17:36:50 +0100 Subject: [PATCH 1/1] tevent: keep a linked list of fd_events metze --- lib/tevent/tevent_aio.c | 48 +++++++++---------------------- lib/tevent/tevent_epoll.c | 47 +++++++++--------------------- lib/tevent/tevent_fd.c | 43 ++++++++++++++++++++++++++++ lib/tevent/tevent_internal.h | 12 ++++++++ lib/tevent/tevent_select.c | 55 +++++++++++------------------------- lib/tevent/tevent_standard.c | 53 +++++++++++++--------------------- 6 files changed, 116 insertions(+), 142 deletions(-) diff --git a/lib/tevent/tevent_aio.c b/lib/tevent/tevent_aio.c index 28134bef5ee..330794f8c5e 100644 --- a/lib/tevent/tevent_aio.c +++ b/lib/tevent/tevent_aio.c @@ -47,12 +47,6 @@ struct aio_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; - /* list of filedescriptor events */ - struct tevent_fd *fd_events; - - /* number of registered fd event handlers */ - int num_fd_events; - uint32_t destruction_count; io_context_t ioctx; @@ -118,7 +112,7 @@ static void epoll_check_reopen(struct aio_event_context *aio_ev) return; } aio_ev->pid = getpid(); - for (fde=aio_ev->fd_events;fde;fde=fde->next) { + for (fde=aio_ev->ev->fd_events;fde;fde=fde->next) { epoll_add_event(aio_ev, fde); } } @@ -159,8 +153,6 @@ static void epoll_del_event(struct aio_event_context *aio_ev, struct tevent_fd * { struct epoll_event event; - DLIST_REMOVE(aio_ev->fd_events, fde); - if (aio_ev->epoll_fd == -1) return; fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; @@ -219,7 +211,6 @@ static void epoll_change_event(struct aio_event_context *aio_ev, struct tevent_f /* there's no aio_event attached to the fde */ if (want_read || (want_write && !got_error)) { - DLIST_ADD(aio_ev->fd_events, fde); epoll_add_event(aio_ev, fde); return; } @@ -389,22 +380,20 @@ static int aio_event_context_init(struct tevent_context *ev) static int aio_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); + struct aio_event_context *aio_ev = NULL; - epoll_check_reopen(aio_ev); + if (ev) { + aio_ev = talloc_get_type(ev->additional_data, + struct aio_event_context); - aio_ev->num_fd_events--; - aio_ev->destruction_count++; + epoll_check_reopen(aio_ev); - epoll_del_event(aio_ev, fde); + aio_ev->destruction_count++; - if (fde->close_fn) { - fde->close_fn(ev, fde, fde->fd, fde->private_data); - fde->fd = -1; + epoll_del_event(aio_ev, fde); } - return 0; + return tevent_common_fd_destructor(fde); } /* @@ -424,24 +413,13 @@ static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX epoll_check_reopen(aio_ev); - fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); if (!fde) return NULL; - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->close_fn = NULL; - fde->private_data = private_data; - fde->handler_name = handler_name; - fde->location = location; - fde->additional_flags = 0; - fde->additional_data = NULL; - - aio_ev->num_fd_events++; talloc_set_destructor(fde, aio_event_fd_destructor); - DLIST_ADD(aio_ev->fd_events, fde); epoll_add_event(aio_ev, fde); return fde; @@ -493,7 +471,7 @@ static int aio_event_loop_wait(struct tevent_context *ev) { struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, struct aio_event_context); - while (aio_ev->num_fd_events) { + while (aio_ev->ev->fd_events) { if (aio_event_loop_once(ev) != 0) { break; } diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index 9dc6e8ba5ed..b90e4c757e6 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -31,12 +31,6 @@ struct epoll_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; - /* list of filedescriptor events */ - struct tevent_fd *fd_events; - - /* number of registered fd event handlers */ - int num_fd_events; - /* this is changed by the destructors for the fd event type. It is used to detect event destruction by event handlers, which means the code that is calling the event @@ -120,7 +114,7 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) return; } epoll_ev->pid = getpid(); - for (fde=epoll_ev->fd_events;fde;fde=fde->next) { + for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) { epoll_add_event(epoll_ev, fde); } } @@ -345,24 +339,20 @@ static int epoll_event_context_init(struct tevent_context *ev) static int epoll_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; - struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, - struct epoll_event_context); + struct epoll_event_context *epoll_ev = NULL; - epoll_check_reopen(epoll_ev); + if (ev) { + epoll_ev = talloc_get_type(ev->additional_data, + struct epoll_event_context); - epoll_ev->num_fd_events--; - epoll_ev->destruction_count++; + epoll_check_reopen(epoll_ev); - DLIST_REMOVE(epoll_ev->fd_events, fde); - - epoll_del_event(epoll_ev, fde); + epoll_ev->destruction_count++; - if (fde->close_fn) { - fde->close_fn(ev, fde, fde->fd, fde->private_data); - fde->fd = -1; + epoll_del_event(epoll_ev, fde); } - return 0; + return tevent_common_fd_destructor(fde); } /* @@ -382,24 +372,13 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT epoll_check_reopen(epoll_ev); - fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); if (!fde) return NULL; - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->close_fn = NULL; - fde->private_data = private_data; - fde->handler_name = handler_name; - fde->location = location; - fde->additional_flags = 0; - fde->additional_data = NULL; - - epoll_ev->num_fd_events++; talloc_set_destructor(fde, epoll_event_fd_destructor); - DLIST_ADD(epoll_ev->fd_events, fde); epoll_add_event(epoll_ev, fde); return fde; @@ -451,7 +430,7 @@ static int epoll_event_loop_wait(struct tevent_context *ev) { struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, struct epoll_event_context); - while (epoll_ev->num_fd_events) { + while (epoll_ev->ev->fd_events) { if (epoll_event_loop_once(ev) != 0) { break; } diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c index d450e2168de..acba2c7712d 100644 --- a/lib/tevent/tevent_fd.c +++ b/lib/tevent/tevent_fd.c @@ -24,6 +24,49 @@ #include "tevent_internal.h" #include "tevent_util.h" +int tevent_common_fd_destructor(struct tevent_fd *fde) +{ + if (fde->event_ctx) { + DLIST_REMOVE(fde->event_ctx->fd_events, fde); + } + + if (fde->close_fn) { + fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data); + fde->fd = -1; + } + + return 0; +} + +struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_fd *fde; + + fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + if (!fde) return NULL; + + fde->event_ctx = ev; + fde->fd = fd; + fde->flags = flags; + fde->handler = handler; + fde->close_fn = NULL; + fde->private_data = private_data; + fde->handler_name = handler_name; + fde->location = location; + fde->additional_flags = 0; + fde->additional_data = NULL; + + DLIST_ADD(ev->fd_events, fde); + + talloc_set_destructor(fde, tevent_common_fd_destructor); + + return fde; +} uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde) { return fde->flags; diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index e090ee2bb1b..f58bb90816f 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -130,6 +130,9 @@ struct tevent_context { /* the specific events implementation */ const struct tevent_ops *ops; + /* list of fd events - used by common code */ + struct tevent_fd *fd_events; + /* list of timed events - used by common code */ struct tevent_timer *timer_events; @@ -149,6 +152,15 @@ struct tevent_context { bool tevent_register_backend(const char *name, const struct tevent_ops *ops); +int tevent_common_fd_destructor(struct tevent_fd *fde); +struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, + uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); 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); diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c index c1b01bb84fe..64f2dd24f2b 100644 --- a/lib/tevent/tevent_select.c +++ b/lib/tevent/tevent_select.c @@ -18,11 +18,6 @@ along with this program. If not, see . */ -/* - This is SAMBA's default event loop code - -*/ - #include "replace.h" #include "system/filesys.h" #include "system/select.h" @@ -34,12 +29,6 @@ struct select_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; - /* list of filedescriptor events */ - struct tevent_fd *fd_events; - - /* list of timed events */ - struct tevent_timer *timed_events; - /* the maximum file descriptor number in fd_events */ int maxfd; @@ -74,7 +63,7 @@ static void calc_maxfd(struct select_event_context *select_ev) struct tevent_fd *fde; select_ev->maxfd = 0; - for (fde = select_ev->fd_events; fde; fde = fde->next) { + for (fde = select_ev->ev->fd_events; fde; fde = fde->next) { if (fde->fd > select_ev->maxfd) { select_ev->maxfd = fde->fd; } @@ -93,22 +82,20 @@ static void calc_maxfd(struct select_event_context *select_ev) static int select_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; - struct select_event_context *select_ev = talloc_get_type(ev->additional_data, - struct select_event_context); + struct select_event_context *select_ev = NULL; - if (select_ev->maxfd == fde->fd) { - select_ev->maxfd = EVENT_INVALID_MAXFD; - } + if (ev) { + select_ev = talloc_get_type(ev->additional_data, + struct select_event_context); - DLIST_REMOVE(select_ev->fd_events, fde); - select_ev->destruction_count++; + if (select_ev->maxfd == fde->fd) { + select_ev->maxfd = EVENT_INVALID_MAXFD; + } - if (fde->close_fn) { - fde->close_fn(ev, fde, fde->fd, fde->private_data); - fde->fd = -1; + select_ev->destruction_count++; } - return 0; + return tevent_common_fd_destructor(fde); } /* @@ -126,21 +113,11 @@ static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_C struct select_event_context); struct tevent_fd *fde; - fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); if (!fde) return NULL; - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->close_fn = NULL; - fde->private_data = private_data; - fde->handler_name = handler_name; - fde->location = location; - fde->additional_flags = 0; - fde->additional_data = NULL; - - DLIST_ADD(select_ev->fd_events, fde); if (fde->fd > select_ev->maxfd) { select_ev->maxfd = fde->fd; } @@ -168,7 +145,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru FD_ZERO(&w_fds); /* setup any fd events */ - for (fde = select_ev->fd_events; fde; fde = fde->next) { + for (fde = select_ev->ev->fd_events; fde; fde = fde->next) { if (fde->flags & TEVENT_FD_READ) { FD_SET(fde->fd, &r_fds); } @@ -212,7 +189,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru /* at least one file descriptor is ready - check which ones and call the handler, being careful to allow the handler to remove itself when called */ - for (fde = select_ev->fd_events; fde; fde = fde->next) { + for (fde = select_ev->ev->fd_events; fde; fde = fde->next) { uint16_t flags = 0; if (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ; @@ -255,7 +232,7 @@ static int select_event_loop_wait(struct tevent_context *ev) struct select_event_context); select_ev->exit_code = 0; - while (select_ev->fd_events && select_ev->exit_code == 0) { + while (ev->fd_events && select_ev->exit_code == 0) { if (select_event_loop_once(ev) != 0) { break; } diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c index 2d8a2305d9c..ee93991def9 100644 --- a/lib/tevent/tevent_standard.c +++ b/lib/tevent/tevent_standard.c @@ -38,9 +38,6 @@ struct std_event_context { /* a pointer back to the generic event_context */ struct tevent_context *ev; - /* list of filedescriptor events */ - struct tevent_fd *fd_events; - /* the maximum file descriptor number in fd_events */ int maxfd; @@ -134,7 +131,7 @@ static void epoll_check_reopen(struct std_event_context *std_ev) return; } std_ev->pid = getpid(); - for (fde=std_ev->fd_events;fde;fde=fde->next) { + for (fde=std_ev->ev->fd_events;fde;fde=fde->next) { epoll_add_event(std_ev, fde); } } @@ -358,7 +355,7 @@ static void calc_maxfd(struct std_event_context *std_ev) struct tevent_fd *fde; std_ev->maxfd = 0; - for (fde = std_ev->fd_events; fde; fde = fde->next) { + for (fde = std_ev->ev->fd_events; fde; fde = fde->next) { if (fde->fd > std_ev->maxfd) { std_ev->maxfd = fde->fd; } @@ -377,26 +374,24 @@ static void calc_maxfd(struct std_event_context *std_ev) static int std_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; - struct std_event_context *std_ev = talloc_get_type(ev->additional_data, - struct std_event_context); + struct std_event_context *std_ev = NULL; - epoll_check_reopen(std_ev); + if (ev) { + std_ev = talloc_get_type(ev->additional_data, + struct std_event_context); - if (std_ev->maxfd == fde->fd) { - std_ev->maxfd = EVENT_INVALID_MAXFD; - } + epoll_check_reopen(std_ev); - DLIST_REMOVE(std_ev->fd_events, fde); - std_ev->destruction_count++; + if (std_ev->maxfd == fde->fd) { + std_ev->maxfd = EVENT_INVALID_MAXFD; + } - epoll_del_event(std_ev, fde); + std_ev->destruction_count++; - if (fde->close_fn) { - fde->close_fn(ev, fde, fde->fd, fde->private_data); - fde->fd = -1; + epoll_del_event(std_ev, fde); } - return 0; + return tevent_common_fd_destructor(fde); } /* @@ -416,21 +411,11 @@ static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX epoll_check_reopen(std_ev); - fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); if (!fde) return NULL; - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->close_fn = NULL; - fde->private_data = private_data; - fde->handler_name = handler_name; - fde->location = location; - fde->additional_flags = 0; - fde->additional_data = NULL; - - DLIST_ADD(std_ev->fd_events, fde); if ((std_ev->maxfd != EVENT_INVALID_MAXFD) && (fde->fd > std_ev->maxfd)) { std_ev->maxfd = fde->fd; @@ -481,7 +466,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva FD_ZERO(&w_fds); /* setup any fd events */ - for (fde = std_ev->fd_events; fde; fde = fde->next) { + for (fde = std_ev->ev->fd_events; fde; fde = fde->next) { if (fde->flags & TEVENT_FD_READ) { FD_SET(fde->fd, &r_fds); } @@ -525,7 +510,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva /* at least one file descriptor is ready - check which ones and call the handler, being careful to allow the handler to remove itself when called */ - for (fde = std_ev->fd_events; fde; fde = fde->next) { + for (fde = std_ev->ev->fd_events; fde; fde = fde->next) { uint16_t flags = 0; if (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ; @@ -574,7 +559,7 @@ static int std_event_loop_wait(struct tevent_context *ev) struct std_event_context); std_ev->exit_code = 0; - while (std_ev->fd_events && std_ev->exit_code == 0) { + while (ev->fd_events && std_ev->exit_code == 0) { if (std_event_loop_once(ev) != 0) { break; } -- 2.34.1