tevent: keep a linked list of fd_events
authorStefan Metzmacher <metze@samba.org>
Mon, 5 Jan 2009 16:36:50 +0000 (17:36 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 5 Jan 2009 21:44:53 +0000 (22:44 +0100)
metze

lib/tevent/tevent_aio.c
lib/tevent/tevent_epoll.c
lib/tevent/tevent_fd.c
lib/tevent/tevent_internal.h
lib/tevent/tevent_select.c
lib/tevent/tevent_standard.c

index 28134bef5eeb9366a60d78cd5fc8612d7faa90f6..330794f8c5eab3f8fb1473a715077a5814e4ed92 100644 (file)
@@ -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;
                }
index 9dc6e8ba5edb29bbd5c780d153050121ec7e9267..b90e4c757e604834ca73c16875edab20348c0a52 100644 (file)
@@ -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;
                }
index d450e2168deeec72e5455f08996bf35828cab42e..acba2c7712d730ca23ecee3a18a4fddee6bbd57e 100644 (file)
 #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;
index e090ee2bb1bd4fb86834345904f25d0dfca96a88..f58bb90816f9ed9ca8cb033c7db7a3f6ad3c9fe2 100644 (file)
@@ -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);
index c1b01bb84febef880a85c7f4ffc9eaf0340d7f34..64f2dd24f2b6664dd82c74307a1852b88a36889f 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-/*
-  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;
                }
index 2d8a2305d9cbc1faedaf9b1b1334ef58f86a2a8b..ee93991def967c0796f4716460f62cd652a72595 100644 (file)
@@ -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;
                }