s3:events: register as tevent backend
authorStefan Metzmacher <metze@samba.org>
Sun, 4 Jan 2009 18:29:12 +0000 (19:29 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 5 Jan 2009 14:07:36 +0000 (15:07 +0100)
metze

source3/include/event.h
source3/lib/events.c

index 3d40000cb845acf9261162d808a6664891027a10..93112a86fa3fa5d8e389de45e16d26c8f1099720 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-struct event_context;
-struct fd_event;
-struct timed_event;
+#define TEVENT_COMPAT_DEFINES
+#include <tevent.h>
 
-/* bits for file descriptor event flags */
-#define EVENT_FD_READ 1
-#define EVENT_FD_WRITE 2
+#undef event_context_init
+#define event_context_init(mem_ctx) s3_tevent_context_init(mem_ctx)
 
 /* The following definitions come from lib/events.c  */
 
-struct timed_event *_event_add_timed(struct event_context *event_ctx,
-                               TALLOC_CTX *mem_ctx,
-                               struct timeval when,
-                               const char *event_name,
-                               void (*handler)(struct event_context *event_ctx,
-                                               struct timed_event *te,
-                                               struct timeval now,
-                                               void *private_data),
-                               void *private_data);
-#define event_add_timed(event_ctx, mem_ctx, when, handler, private_data) \
-       _event_add_timed(event_ctx, mem_ctx, when, #handler, handler, private_data)
-struct fd_event *event_add_fd(struct event_context *event_ctx,
-                             TALLOC_CTX *mem_ctx,
-                             int fd, uint16_t flags,
-                             void (*handler)(struct event_context *event_ctx,
-                                             struct fd_event *event,
-                                             uint16 flags,
-                                             void *private_data),
-                             void *private_data);
 void event_fd_set_writeable(struct fd_event *fde);
 void event_fd_set_not_writeable(struct fd_event *fde);
 void event_fd_set_readable(struct fd_event *fde);
@@ -59,8 +38,7 @@ bool run_events(struct event_context *event_ctx,
                int selrtn, fd_set *read_fds, fd_set *write_fds);
 struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
                                         struct timeval *to_ret);
-int event_loop_once(struct event_context *ev);
 void event_context_reinit(struct event_context *ev);
-struct event_context *event_context_init(TALLOC_CTX *mem_ctx);
 void dump_event_list(struct event_context *event_ctx);
+struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx);
 
index 9e9d335c7b564f22e70e6e2ab2a13b6a74840122..be2fdcb68f3950c9b757631485878b43786e0606 100644 (file)
 */
 
 #include "includes.h"
+#include <tevent_internal.h>
 
-struct timed_event {
-       struct timed_event *next, *prev;
-       struct event_context *event_ctx;
-       struct timeval when;
-       const char *event_name;
-       void (*handler)(struct event_context *event_ctx,
-                       struct timed_event *te,
-                       struct timeval now,
-                       void *private_data);
-       void *private_data;
+struct s3_event_context {
+       struct tevent_context *ev;
+       struct tevent_fd *fd_events;
 };
 
-struct fd_event {
-       struct fd_event *prev, *next;
-       struct event_context *event_ctx;
-       int fd;
-       uint16_t flags; /* see EVENT_FD_* flags */
-       void (*handler)(struct event_context *event_ctx,
-                       struct fd_event *event,
-                       uint16 flags,
-                       void *private_data);
-       void *private_data;
-};
-
-struct event_context {
-       struct timed_event *timed_events;
-       struct fd_event *fd_events;
-};
-
-static int timed_event_destructor(struct timed_event *te)
+static int s3_event_timer_destructor(struct tevent_timer *te)
 {
-       DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
-               te->event_name));
+       DEBUG(10, ("Destroying timer event %p \"%s\"\n",
+                 te, te->handler_name));
        if (te->event_ctx != NULL) {
-               DLIST_REMOVE(te->event_ctx->timed_events, te);
+               DLIST_REMOVE(te->event_ctx->timer_events, te);
        }
        return 0;
 }
@@ -63,23 +40,23 @@ static int timed_event_destructor(struct timed_event *te)
  Add te by time.
 ****************************************************************************/
 
-static void add_event_by_time(struct timed_event *te)
+static void add_event_by_time(struct tevent_timer *te)
 {
-       struct event_context *ctx = te->event_ctx;
-       struct timed_event *last_te, *cur_te;
+       struct tevent_context *ctx = te->event_ctx;
+       struct tevent_timer *last_te, *cur_te;
 
        /* Keep the list ordered by time. We must preserve this. */
        last_te = NULL;
-       for (cur_te = ctx->timed_events; cur_te; cur_te = cur_te->next) {
+       for (cur_te = ctx->timer_events; cur_te; cur_te = cur_te->next) {
                /* if the new event comes before the current one break */
-               if (!timeval_is_zero(&cur_te->when) &&
-                               timeval_compare(&te->when, &cur_te->when) < 0) {
+               if (!timeval_is_zero(&cur_te->next_event) &&
+                   timeval_compare(&te->next_event, &cur_te->next_event) < 0) {
                        break;
                }
                last_te = cur_te;
        }
 
-       DLIST_ADD_AFTER(ctx->timed_events, te, last_te);
+       DLIST_ADD_AFTER(ctx->timer_events, te, last_te);
 }
 
 /****************************************************************************
@@ -88,115 +65,128 @@ static void add_event_by_time(struct timed_event *te)
  handed to it.
 ****************************************************************************/
 
-struct timed_event *_event_add_timed(struct event_context *event_ctx,
-                               TALLOC_CTX *mem_ctx,
-                               struct timeval when,
-                               const char *event_name,
-                               void (*handler)(struct event_context *event_ctx,
-                                               struct timed_event *te,
-                                               struct timeval now,
-                                               void *private_data),
-                               void *private_data)
+static struct tevent_timer *s3_event_add_timer(struct tevent_context *event_ctx,
+                                              TALLOC_CTX *mem_ctx,
+                                              struct timeval when,
+                                              tevent_timer_handler_t handler,
+                                              void *private_data,
+                                              const char *handler_name,
+                                              const char *location)
 {
-       struct timed_event *te;
+       struct tevent_timer *te;
 
-       te = TALLOC_P(mem_ctx, struct timed_event);
+       te = TALLOC_P(mem_ctx, struct tevent_timer);
        if (te == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return NULL;
        }
 
        te->event_ctx = event_ctx;
-       te->when = when;
-       te->event_name = event_name;
+       te->next_event = when;
        te->handler = handler;
        te->private_data = private_data;
+       te->handler_name = handler_name;
+       te->location = location;
+       te->additional_data = NULL;
 
        add_event_by_time(te);
 
-       talloc_set_destructor(te, timed_event_destructor);
+       talloc_set_destructor(te, s3_event_timer_destructor);
 
-       DEBUG(10, ("Added timed event \"%s\": %lx\n", event_name,
-                       (unsigned long)te));
+       DEBUG(10, ("Added timed event \"%s\": %p\n", handler_name, te));
        return te;
 }
 
-static int fd_event_destructor(struct fd_event *fde)
+static int s3_event_fd_destructor(struct tevent_fd *fde)
 {
        if (fde->event_ctx != NULL) {
-               DLIST_REMOVE(fde->event_ctx->fd_events, fde);
+               struct s3_event_context *ev3;
+               ev3 = talloc_get_type(fde->event_ctx->additional_data,
+                                     struct s3_event_context);
+               DLIST_REMOVE(ev3->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 fd_event *event_add_fd(struct event_context *event_ctx,
-                             TALLOC_CTX *mem_ctx,
-                             int fd, uint16_t flags,
-                             void (*handler)(struct event_context *event_ctx,
-                                             struct fd_event *event,
-                                             uint16 flags,
-                                             void *private_data),
-                             void *private_data)
+static struct tevent_fd *s3_event_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 fd_event *fde;
+       struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
+                                                      struct s3_event_context);
+       struct tevent_fd *fde;
 
-       if (!(fde = TALLOC_P(mem_ctx, struct fd_event))) {
+       if (!(fde = TALLOC_P(mem_ctx, struct tevent_fd))) {
                return NULL;
        }
 
-       fde->event_ctx = event_ctx;
+       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;
 
-       DLIST_ADD(event_ctx->fd_events, fde);
+       DLIST_ADD(ev3->fd_events, fde);
 
-       talloc_set_destructor(fde, fd_event_destructor);
+       talloc_set_destructor(fde, s3_event_fd_destructor);
        return fde;
 }
 
-void event_fd_set_writeable(struct fd_event *fde)
+void event_fd_set_writeable(struct tevent_fd *fde)
 {
-       fde->flags |= EVENT_FD_WRITE;
+       TEVENT_FD_WRITEABLE(fde);
 }
 
-void event_fd_set_not_writeable(struct fd_event *fde)
+void event_fd_set_not_writeable(struct tevent_fd *fde)
 {
-       fde->flags &= ~EVENT_FD_WRITE;
+       TEVENT_FD_NOT_WRITEABLE(fde);
 }
 
-void event_fd_set_readable(struct fd_event *fde)
+void event_fd_set_readable(struct tevent_fd *fde)
 {
-       fde->flags |= EVENT_FD_READ;
+       TEVENT_FD_READABLE(fde);
 }
 
-void event_fd_set_not_readable(struct fd_event *fde)
+void event_fd_set_not_readable(struct tevent_fd *fde)
 {
-       fde->flags &= ~EVENT_FD_READ;
+       TEVENT_FD_NOT_READABLE(fde);
 }
 
 /*
  * Return if there's something in the queue
  */
 
-bool event_add_to_select_args(struct event_context *event_ctx,
+bool event_add_to_select_args(struct tevent_context *ev,
                              const struct timeval *now,
                              fd_set *read_fds, fd_set *write_fds,
                              struct timeval *timeout, int *maxfd)
 {
-       struct fd_event *fde;
+       struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
+                                                      struct s3_event_context);
+       struct tevent_fd *fde;
        struct timeval diff;
-       bool ret = False;
+       bool ret = false;
 
-       for (fde = event_ctx->fd_events; fde; fde = fde->next) {
+       for (fde = ev3->fd_events; fde; fde = fde->next) {
                if (fde->flags & EVENT_FD_READ) {
                        FD_SET(fde->fd, read_fds);
-                       ret = True;
+                       ret = true;
                }
                if (fde->flags & EVENT_FD_WRITE) {
                        FD_SET(fde->fd, write_fds);
-                       ret = True;
+                       ret = true;
                }
 
                if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE))
@@ -205,46 +195,48 @@ bool event_add_to_select_args(struct event_context *event_ctx,
                }
        }
 
-       if (event_ctx->timed_events == NULL) {
+       if (ev->timer_events == NULL) {
                return ret;
        }
 
-       diff = timeval_until(now, &event_ctx->timed_events->when);
+       diff = timeval_until(now, &ev->timer_events->next_event);
        *timeout = timeval_min(timeout, &diff);
 
-       return True;
+       return true;
 }
 
-bool run_events(struct event_context *event_ctx,
+bool run_events(struct tevent_context *ev,
                int selrtn, fd_set *read_fds, fd_set *write_fds)
 {
-       bool fired = False;
-       struct fd_event *fde, *next;
+       struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
+                                                      struct s3_event_context);
+       bool fired = false;
+       struct tevent_fd *fde, *next;
 
        /* Run all events that are pending, not just one (as we
           did previously. */
 
-       while (event_ctx->timed_events) {
+       while (ev->timer_events) {
                struct timeval now;
                GetTimeOfDay(&now);
 
                if (timeval_compare(
-                           &now, &event_ctx->timed_events->when) < 0) {
+                           &now, &ev->timer_events->next_event) < 0) {
                        /* Nothing to do yet */
                        DEBUG(11, ("run_events: Nothing to do\n"));
                        break;
                }
 
-               DEBUG(10, ("Running event \"%s\" %lx\n",
-                          event_ctx->timed_events->event_name,
-                          (unsigned long)event_ctx->timed_events));
+               DEBUG(10, ("Running event \"%s\" %p\n",
+                          ev->timer_events->handler_name,
+                          ev->timer_events));
 
-               event_ctx->timed_events->handler(
-                       event_ctx,
-                       event_ctx->timed_events, now,
-                       event_ctx->timed_events->private_data);
+               ev->timer_events->handler(
+                       ev,
+                       ev->timer_events, now,
+                       ev->timer_events->private_data);
 
-               fired = True;
+               fired = true;
        }
 
        if (fired) {
@@ -252,7 +244,7 @@ bool run_events(struct event_context *event_ctx,
                 * We might have changed the socket status during the timed
                 * events, return to run select again.
                 */
-               return True;
+               return true;
        }
 
        if (selrtn == 0) {
@@ -262,7 +254,7 @@ bool run_events(struct event_context *event_ctx,
                return fired;
        }
 
-       for (fde = event_ctx->fd_events; fde; fde = next) {
+       for (fde = ev3->fd_events; fde; fde = next) {
                uint16 flags = 0;
 
                next = fde->next;
@@ -270,8 +262,8 @@ bool run_events(struct event_context *event_ctx,
                if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
 
                if (flags & fde->flags) {
-                       fde->handler(event_ctx, fde, flags, fde->private_data);
-                       fired = True;
+                       fde->handler(ev, fde, flags, fde->private_data);
+                       fired = true;
                }
        }
 
@@ -279,17 +271,17 @@ bool run_events(struct event_context *event_ctx,
 }
 
 
-struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
+struct timeval *get_timed_events_timeout(struct tevent_context *ev,
                                         struct timeval *to_ret)
 {
        struct timeval now;
 
-       if (event_ctx->timed_events == NULL) {
+       if (ev->timer_events == NULL) {
                return NULL;
        }
 
        now = timeval_current();
-       *to_ret = timeval_until(&now, &event_ctx->timed_events->when);
+       *to_ret = timeval_until(&now, &ev->timer_events->next_event);
 
        DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec,
                (int)to_ret->tv_usec));
@@ -297,7 +289,7 @@ struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
        return to_ret;
 }
 
-int event_loop_once(struct event_context *ev)
+static int s3_event_loop_once(struct tevent_context *ev)
 {
        struct timeval now, to;
        fd_set r_fds, w_fds;
@@ -331,45 +323,60 @@ int event_loop_once(struct event_context *ev)
        return 0;
 }
 
-static int event_context_destructor(struct event_context *ev)
+static int s3_event_loop_wait(struct tevent_context *ev)
+{
+       int ret = 0;
+
+       while (ret == 0) {
+               ret = s3_event_loop_once(ev);
+       }
+
+       return ret;
+}
+
+static int s3_event_context_destructor(struct tevent_context *ev)
 {
-       while (ev->fd_events != NULL) {
-               ev->fd_events->event_ctx = NULL;
-               DLIST_REMOVE(ev->fd_events, ev->fd_events);
+       struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
+                                                      struct s3_event_context);
+       while (ev3->fd_events != NULL) {
+               ev3->fd_events->event_ctx = NULL;
+               DLIST_REMOVE(ev3->fd_events, ev3->fd_events);
        }
-       while (ev->timed_events != NULL) {
-               ev->timed_events->event_ctx = NULL;
-               DLIST_REMOVE(ev->timed_events, ev->timed_events);
+       while (ev->timer_events != NULL) {
+               ev->timer_events->event_ctx = NULL;
+               DLIST_REMOVE(ev->timer_events, ev3->ev->timer_events);
        }
        return 0;
 }
 
-void event_context_reinit(struct event_context *ev)
+void event_context_reinit(struct tevent_context *ev)
 {
-       event_context_destructor(ev);
+       s3_event_context_destructor(ev);
        return;
 }
 
-struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
+static int s3_event_context_init(struct tevent_context *ev)
 {
-       struct event_context *result;
+       struct s3_event_context *ev3;
 
-       result = TALLOC_ZERO_P(mem_ctx, struct event_context);
-       if (result == NULL) {
-               return NULL;
-       }
+       ev3 = talloc_zero(ev, struct s3_event_context);
+       if (!ev3) return -1;
+       ev3->ev = ev;
 
-       talloc_set_destructor(result, event_context_destructor);
-       return result;
+       ev->additional_data = ev3;
+       talloc_set_destructor(ev, s3_event_context_destructor);
+       return 0;
 }
 
-void dump_event_list(struct event_context *event_ctx)
+void dump_event_list(struct tevent_context *ev)
 {
-       struct timed_event *te;
-       struct fd_event *fe;
+       struct s3_event_context *ev3 = talloc_get_type(ev->additional_data,
+                                                      struct s3_event_context);
+       struct tevent_timer *te;
+       struct tevent_fd *fe;
        struct timeval evt, now;
 
-       if (!event_ctx) {
+       if (!ev) {
                return;
        }
 
@@ -377,22 +384,50 @@ void dump_event_list(struct event_context *event_ctx)
 
        DEBUG(10,("dump_event_list:\n"));
 
-       for (te = event_ctx->timed_events; te; te = te->next) {
+       for (te = ev->timer_events; te; te = te->next) {
 
-               evt = timeval_until(&now, &te->when);
+               evt = timeval_until(&now, &te->next_event);
 
-               DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds (at %s)\n",
-                          te->event_name,
-                          (unsigned long)te,
+               DEBUGADD(10,("Timed Event \"%s\" %p handled in %d seconds (at %s)\n",
+                          te->handler_name,
+                          te,
                           (int)evt.tv_sec,
-                          http_timestring(talloc_tos(), te->when.tv_sec)));
+                          http_timestring(talloc_tos(), te->next_event.tv_sec)));
        }
 
-       for (fe = event_ctx->fd_events; fe; fe = fe->next) {
+       for (fe = ev3->fd_events; fe; fe = fe->next) {
 
-               DEBUGADD(10,("FD Event %d %lx, flags: 0x%04x\n",
+               DEBUGADD(10,("FD Event %d %p, flags: 0x%04x\n",
                           fe->fd,
-                          (unsigned long)fe,
+                          fe,
                           fe->flags));
        }
 }
+
+static const struct tevent_ops s3_event_ops = {
+       .context_init   = s3_event_context_init,
+       .add_fd         = s3_event_add_fd,
+       .set_fd_close_fn= tevent_common_fd_set_close_fn,
+       .get_fd_flags   = tevent_common_fd_get_flags,
+       .set_fd_flags   = tevent_common_fd_set_flags,
+       .add_timer      = s3_event_add_timer,
+       .loop_once      = s3_event_loop_once,
+       .loop_wait      = s3_event_loop_wait,
+};
+
+static bool s3_tevent_init(void)
+{
+       static bool initialized;
+       if (initialized) {
+               return true;
+       }
+       initialized = tevent_register_backend("s3", &s3_event_ops);
+       tevent_set_default_backend("s3");
+       return initialized;
+}
+
+struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx)
+{
+       s3_tevent_init();
+       return tevent_context_init_byname(mem_ctx, "s3");
+}