From b213b70c089046f426e1e3f2f733e42a02e2cbfe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Jan 2007 09:35:49 +0000 Subject: r20539: - split the common timer related events code into events_timed.c - make it easier to plug in a new events backend - add simpler 'select' and 'epoll' backends This is part of the effort to add good AIO support. The events_aio.c backend is done, but sometimes dies with a SEGV, which is why it isn't enabled yet. (This used to be commit 934f18283dbc7958944931a93a854526bcd54884) --- source4/lib/events/events.c | 98 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) (limited to 'source4/lib/events/events.c') diff --git a/source4/lib/events/events.c b/source4/lib/events/events.c index 585fcb3112..52b431befa 100644 --- a/source4/lib/events/events.c +++ b/source4/lib/events/events.c @@ -57,6 +57,63 @@ #include "includes.h" #include "lib/events/events.h" #include "lib/events/events_internal.h" +#include "lib/util/dlinklist.h" +#include "build.h" + +struct event_ops_list { + struct event_ops_list *next, *prev; + const char *name; + const struct event_ops *ops; +}; + +/* list of registered event backends */ +static struct event_ops_list *event_backends; + +/* + register an events backend +*/ +NTSTATUS event_register_backend(const char *name, const struct event_ops *ops) +{ + struct event_ops_list *e; + e = talloc(talloc_autofree_context(), struct event_ops_list); + NT_STATUS_HAVE_NO_MEMORY(e); + e->name = name; + e->ops = ops; + DLIST_ADD(event_backends, e); + return NT_STATUS_OK; +} + +/* + initialise backends if not already done +*/ +static void event_backend_init(void) +{ + init_module_fn static_init[] = STATIC_LIBEVENTS_MODULES; + init_module_fn *shared_init; + if (event_backends) return; + shared_init = load_samba_modules(NULL, "LIBEVENTS"); + run_init_functions(static_init); + run_init_functions(shared_init); +} + +/* + list available backends +*/ +const char **event_backend_list(TALLOC_CTX *mem_ctx) +{ + const char **list = NULL; + struct event_ops_list *e; + + event_backend_init(); + + for (e=event_backends;e;e=e->next) { + list = str_list_add(list, e->name); + } + + talloc_steal(mem_ctx, list); + + return list; +} /* create a event_context structure for a specific implemementation. @@ -69,7 +126,8 @@ NOTE: use event_context_init() inside of samba! */ -struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data) +static struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, + const struct event_ops *ops) { struct event_context *ev; int ret; @@ -79,7 +137,7 @@ struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct e ev->ops = ops; - ret = ev->ops->context_init(ev, private_data); + ret = ev->ops->context_init(ev); if (ret != 0) { talloc_free(ev); return NULL; @@ -88,6 +146,26 @@ struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct e return ev; } +/* + create a event_context structure. This must be the first events + call, and all subsequent calls pass this event_context as the first + element. Event handlers also receive this as their first argument. +*/ +struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name) +{ + struct event_ops_list *e; + + event_backend_init(); + + for (e=event_backends;e;e=e->next) { + if (strcmp(name, e->name) == 0) { + return event_context_init_ops(mem_ctx, e->ops); + } + } + return NULL; +} + + /* create a event_context structure. This must be the first events call, and all subsequent calls pass this event_context as the first @@ -95,8 +173,7 @@ struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct e */ struct event_context *event_context_init(TALLOC_CTX *mem_ctx) { - const struct event_ops *ops = event_standard_get_ops(); - return event_context_init_ops(mem_ctx, ops, NULL); + return event_context_init_byname(mem_ctx, "standard"); } /* @@ -110,6 +187,19 @@ struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data); } +/* + add a disk aio event +*/ +struct aio_event *event_add_aio(struct event_context *ev, + TALLOC_CTX *mem_ctx, + struct iocb *iocb, + event_aio_handler_t handler, + void *private_data) +{ + if (ev->ops->add_aio == NULL) return NULL; + return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data); +} + /* return the fd event flags */ -- cgit