diff options
author | Simo Sorce <idra@samba.org> | 2008-06-14 11:23:31 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2008-06-14 11:59:19 -0400 |
commit | 2aba4107915611b223daa8c27c52352f57b25bbc (patch) | |
tree | b97a1f2408c3101ca8e66faa6851848d829e4f5f | |
parent | 3443954c2bf971c3506aa40667989a10d5769706 (diff) | |
download | samba-2aba4107915611b223daa8c27c52352f57b25bbc.tar.gz samba-2aba4107915611b223daa8c27c52352f57b25bbc.tar.bz2 samba-2aba4107915611b223daa8c27c52352f57b25bbc.zip |
This patch make it possible to build the events library completely
standalone with no ties to internal samba4 functions
Samba4 itself just uses the plain library, compatibility glue is
in events_s4.c only
(This used to be commit 7109b6a5a19eb2dbef4259104858b171298bad6e)
23 files changed, 427 insertions, 283 deletions
diff --git a/source4/configure.ac b/source4/configure.ac index ca38f6add4..8ec6022d69 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -89,7 +89,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1, SMB_INCLUDE_MK(lib/ldb/python.mk) m4_include(lib/tls/config.m4) -m4_include(lib/events/config.m4) +m4_include(lib/events/libevents.m4) dnl m4_include(auth/kerberos/config.m4) m4_include(scripting/python/config.m4) diff --git a/source4/lib/events/config.m4 b/source4/lib/events/config.m4 deleted file mode 100644 index 180b58cbc6..0000000000 --- a/source4/lib/events/config.m4 +++ /dev/null @@ -1,18 +0,0 @@ -# check for EPOLL and native Linux AIO interface -SMB_ENABLE(EVENTS_EPOLL, NO) -SMB_ENABLE(EVENTS_AIO, NO) -AC_CHECK_HEADERS(sys/epoll.h) -AC_CHECK_FUNCS(epoll_create) -if test x"$ac_cv_header_sys_epoll_h" = x"yes" -a x"$ac_cv_func_epoll_create" = x"yes";then - SMB_ENABLE(EVENTS_EPOLL,YES) - AC_DEFINE(HAVE_EVENTS_EPOLL, 1, [Whether epoll is available]) - - # check for native Linux AIO interface - AC_CHECK_HEADERS(libaio.h) - AC_CHECK_LIB_EXT(aio, AIO_LIBS, io_getevents) - if test x"$ac_cv_header_libaio_h" = x"yes" -a x"$ac_cv_lib_ext_aio_io_getevents" = x"yes";then - SMB_ENABLE(EVENTS_AIO,YES) - AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available]) - fi -fi -SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS) diff --git a/source4/lib/events/config.mk b/source4/lib/events/config.mk index 9d579807c8..8ba5af91a8 100644 --- a/source4/lib/events/config.mk +++ b/source4/lib/events/config.mk @@ -1,13 +1,3 @@ -################################################ -# Start SUBSYSTEM LIBEVENTS -[LIBRARY::LIBEVENTS] -PUBLIC_DEPENDENCIES = LIBTALLOC -OUTPUT_TYPE = STATIC_LIBRARY -CFLAGS = -Ilib/events -# -# End SUBSYSTEM LIBEVENTS -################################################ - ############################## [MODULE::EVENTS_AIO] PRIVATE_DEPENDENCIES = LIBAIO_LINUX @@ -41,19 +31,23 @@ INIT_FUNCTION = s4_events_standard_init EVENTS_STANDARD_OBJ_FILES = $(libeventssrcdir)/events_standard.o -############################## +################################################ # Start SUBSYSTEM LIBEVENTS -[SUBSYSTEM::LIBEVENTS] +[LIBRARY::LIBEVENTS] +PUBLIC_DEPENDENCIES = LIBTALLOC +OUTPUT_TYPE = STATIC_LIBRARY +CFLAGS = -Ilib/events +# # End SUBSYSTEM LIBEVENTS -############################## +################################################ -LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, events.o events_timed.o events_signal.o) +LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, events.o events_timed.o events_signal.o events_debug.o events_util.o events_s4.o) PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h events_internal.h) [PYTHON::swig_events] LIBRARY_REALNAME = samba/_events.$(SHLIBEXT) -PRIVATE_DEPENDENCIES = LIBEVENTS LIBSAMBA-HOSTCONFIG +PRIVATE_DEPENDENCIES = LIBEVENTS LIBSAMBA-HOSTCONFIG LIBSAMBA-UTIL swig_events_OBJ_FILES = $(libeventssrcdir)/events_wrap.o diff --git a/source4/lib/events/configure.ac b/source4/lib/events/configure.ac index 4eb3575aac..26efe82ba4 100644 --- a/source4/lib/events/configure.ac +++ b/source4/lib/events/configure.ac @@ -2,6 +2,7 @@ AC_PREREQ(2.50) AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) AC_DEFUN([SMB_ENABLE], [echo -n ""]) +AC_DEFUN([SMB_EXT_LIB], [echo -n ""]) AC_INIT(events, 1.0.0) AC_CONFIG_SRCDIR([events.c]) AC_CONFIG_HEADER(config.h) diff --git a/source4/lib/events/events.c b/source4/lib/events/events.c index ccc62b4c83..1c94e3436d 100644 --- a/source4/lib/events/events.c +++ b/source4/lib/events/events.c @@ -52,14 +52,7 @@ forever. */ -#if _SAMBA_BUILD_ -#include "includes.h" -#include "lib/util/dlinklist.h" -#include "param/param.h" -#else #include "replace.h" -#include "events_util.h" -#endif #include "events.h" #include "events_internal.h" @@ -70,8 +63,7 @@ struct event_ops_list { }; /* list of registered event backends */ -static struct event_ops_list *event_backends; - +static struct event_ops_list *event_backends = NULL; static char *event_default_backend = NULL; /* @@ -80,11 +72,21 @@ static char *event_default_backend = NULL; bool event_register_backend(const char *name, const struct event_ops *ops) { struct event_ops_list *e; + + for (e = event_backends; e != NULL; e = e->next) { + if (0 == strcmp(e->name, name)) { + /* already registered, skip it */ + return true; + } + } + e = talloc(talloc_autofree_context(), struct event_ops_list); if (e == NULL) return false; + e->name = name; e->ops = ops; DLIST_ADD(event_backends, e); + return true; } @@ -102,25 +104,13 @@ void event_set_default_backend(const char *backend) */ static void event_backend_init(void) { -#if _SAMBA_BUILD_ - NTSTATUS s4_events_standard_init(void); - NTSTATUS s4_events_select_init(void); - NTSTATUS s4_events_epoll_init(void); - NTSTATUS s4_events_aio_init(void); - init_module_fn static_init[] = { STATIC_LIBEVENTS_MODULES }; - if (event_backends) return; - run_init_functions(static_init); -#else - bool events_standard_init(void); - bool events_select_init(void); events_select_init(); events_standard_init(); #if HAVE_EVENTS_EPOLL - { - bool events_epoll_init(void); - events_epoll_init(); - } + events_epoll_init(); #endif +#if HAVE_LINUX_AIO + events_aio_init(); #endif } @@ -135,7 +125,7 @@ const char **event_backend_list(TALLOC_CTX *mem_ctx) event_backend_init(); for (e=event_backends;e;e=e->next) { - list = str_list_add(list, e->name); + list = ev_str_list_add(list, e->name); } talloc_steal(mem_ctx, list); @@ -208,8 +198,6 @@ struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char */ struct event_context *event_context_init(TALLOC_CTX *mem_ctx) { - DEBUG(0, ("New event context requested. Parent: [%s:%p]\n", - mem_ctx?talloc_get_name(mem_ctx):"NULL", mem_ctx)); return event_context_init_byname(mem_ctx, NULL); } diff --git a/source4/lib/events/events.h b/source4/lib/events/events.h index 2868fefc38..750cdfee05 100644 --- a/source4/lib/events/events.h +++ b/source4/lib/events/events.h @@ -42,6 +42,11 @@ typedef void (*event_signal_handler_t)(struct event_context *, struct signal_eve typedef void (*event_aio_handler_t)(struct event_context *, struct aio_event *, int, void *); +#ifdef _SAMBA_BUILD_ +struct event_context *s4_event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); +struct event_context *s4_event_context_init(TALLOC_CTX *mem_ctx); +#endif + struct event_context *event_context_init(TALLOC_CTX *mem_ctx); struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); const char **event_backend_list(TALLOC_CTX *mem_ctx); diff --git a/source4/lib/events/events.mk b/source4/lib/events/events.mk index 64d3fcb9fd..f4b02eae83 100644 --- a/source4/lib/events/events.mk +++ b/source4/lib/events/events.mk @@ -1,14 +1,47 @@ + +EVENTS_SONAME = libevents.$(SHLIBEXT).0 +EVENTS_SOLIB = libevents.$(SHLIBEXT).$(PACKAGE_VERSION) + +libevents.a: $(EVENTS_OBJ) + ar -rv libevents.a $(EVENTS_OBJ) + +libevents.$(SHLIBEXT): $(LIBEVENTS_SOLIB) + ln -fs $< $@ + +$(EVENTS_SONAME): $(EVENTS_SOLIB) + ln -fs $< $@ + dirs:: @mkdir -p lib -LIBEVENTS_SONAME = libevents.$(SHLIBEXT).0 -LIBEVENTS_SOLIB = libevents.$(SHLIBEXT).$(PACKAGE_VERSION) +installdirs:: + mkdir -p $(DESTDIR)$(includedir) + mkdir -p $(DESTDIR)$(libdir) + mkdir -p $(DESTDIR)$(libdir)/pkgconfig + +installheaders:: installdirs + cp $(srcdir)/events.h $(DESTDIR)$(includedir) + +installlibs:: installdirs + cp events.pc $(DESTDIR)$(libdir)/pkgconfig + cp libevents.a $(LIBEVENTS_SOLIB) $(DESTDIR)$(libdir) -LIBEVENTS = libevents.a +install:: all installdirs installheaders installlibs $(PYTHON_INSTALL_TARGET) clean:: - rm -f $(LIBEVENTS_SONAME) $(LIBEVENTS_SOLIB) libevents.a libevents.$(SHLIBEXT) + rm -f $(EVENTS_SONAME) $(EVENTS_SOLIB) libevents.a libevents.$(SHLIBEXT) rm -f events.pc + rm -f _libevents.$(SHLIBEXT) + + +#python stuff + +check-python:: build-python + $(LIB_PATH_VAR)=. PYTHONPATH=".:$(eventsdir)" $(PYTHON) $(eventsdir)/python/tests/simple.py + +install-swig:: + mkdir -p $(DESTDIR)`$(SWIG) -swiglib` + cp events.i $(DESTDIR)`$(SWIG) -swiglib` build-python:: _libevents.$(SHLIBEXT) @@ -18,42 +51,9 @@ events_wrap.o: $(eventsdir)/events_wrap.c _libevents.$(SHLIBEXT): libevents.$(SHLIBEXT) events_wrap.o $(SHLD) $(SHLD_FLAGS) -o $@ events_wrap.o -L. -levents `$(PYTHON_CONFIG) --libs` -install:: installdirs installbin installheaders installlibs \ - $(PYTHON_INSTALL_TARGET) - install-python:: build-python mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"` \ $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` cp $(eventsdir)/events.py $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"` cp _libevents.$(SHLIBEXT) $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` -check-python:: build-python - $(LIB_PATH_VAR)=. PYTHONPATH=".:$(eventsdir)" $(PYTHON) $(eventsdir)/python/tests/simple.py - -install-swig:: - mkdir -p $(DESTDIR)`$(SWIG) -swiglib` - cp events.i $(DESTDIR)`$(SWIG) -swiglib` - -clean:: - rm -f _libevents.$(SHLIBEXT) - -installdirs:: - mkdir -p $(DESTDIR)$(includedir) - mkdir -p $(DESTDIR)$(libdir) - mkdir -p $(DESTDIR)$(libdir)/pkgconfig - -installheaders:: installdirs - cp $(srcdir)/events.h $(DESTDIR)$(includedir) - -installlibs:: all installdirs - cp events.pc $(DESTDIR)$(libdir)/pkgconfig - cp libevents.a $(LIBEVENTS_SOLIB) $(DESTDIR)$(libdir) - -libevents.a: $(EVENTS_OBJ) - ar -rv libevents.a $(EVENTS_OBJ) - -libevents.$(SHLIBEXT): $(LIBEVENTS_SOLIB) - ln -fs $< $@ - -$(LIBEVENTS_SONAME): $(LIBEVENTS_SOLIB) - ln -fs $< $@ diff --git a/source4/lib/events/events.py b/source4/lib/events/events.py index 90695e3d92..f217c29d78 100644 --- a/source4/lib/events/events.py +++ b/source4/lib/events/events.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.35 +# Version 1.3.33 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/lib/events/events_aio.c b/source4/lib/events/events_aio.c index a0417384e0..9d13ea96fd 100644 --- a/source4/lib/events/events_aio.c +++ b/source4/lib/events/events_aio.c @@ -30,12 +30,10 @@ this is _very_ experimental code */ -#include "includes.h" #include "system/filesys.h" #include "system/network.h" -#include "lib/util/dlinklist.h" -#include "lib/events/events.h" -#include "lib/events/events_internal.h" +#include "events.h" +#include "events_internal.h" #include <sys/epoll.h> #include <libaio.h> @@ -114,7 +112,7 @@ static void epoll_check_reopen(struct aio_event_context *aio_ev) close(aio_ev->epoll_fd); aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH); if (aio_ev->epoll_fd == -1) { - DEBUG(0,("Failed to recreate epoll handle after fork\n")); + ev_debug(aio_ev->ev, EV_DEBUG_FATAL, "Failed to recreate epoll handle after fork\n"); return; } aio_ev->pid = getpid(); @@ -566,12 +564,3 @@ bool events_aio_init(void) return event_register_backend("aio", &aio_event_ops); } -#if _SAMBA_BUILD_ -NTSTATUS s4_events_aio_init(void) -{ - if (!events_aio_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} -#endif diff --git a/source4/lib/events/events_debug.c b/source4/lib/events/events_debug.c new file mode 100644 index 0000000000..70b85d47e4 --- /dev/null +++ b/source4/lib/events/events_debug.c @@ -0,0 +1,78 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Jelmer Vernooij 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" +#include "events.h" +#include "events_internal.h" + +/******************************************************************** + * Debug wrapper functions, modeled (with lot's of code copied as is) + * after the ev debug wrapper functions + ********************************************************************/ + +/* + this allows the user to choose their own debug function +*/ +int ev_set_debug(struct event_context *ev, + void (*debug)(void *context, enum ev_debug_level level, + const char *fmt, va_list ap), + void *context) +{ + ev->debug_ops.debug = debug; + ev->debug_ops.context = context; + return 0; +} + +/* + debug function for ev_set_debug_stderr +*/ +static void ev_debug_stderr(void *context, enum ev_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); +static void ev_debug_stderr(void *context, enum ev_debug_level level, + const char *fmt, va_list ap) +{ + if (level <= EV_DEBUG_WARNING) { + vfprintf(stderr, fmt, ap); + } +} + +/* + convenience function to setup debug messages on stderr + messages of level EV_DEBUG_WARNING and higher are printed +*/ +int ev_set_debug_stderr(struct event_context *ev) +{ + return ev_set_debug(ev, ev_debug_stderr, ev); +} + +/* + log a message +*/ +void ev_debug(struct event_context *ev, enum ev_debug_level level, const char *fmt, ...) +{ + va_list ap; + if (ev->debug_ops.debug == NULL) { + ev_set_debug_stderr(ev); + } + va_start(ap, fmt); + ev->debug_ops.debug(ev->debug_ops.context, level, fmt, ap); + va_end(ap); +} + diff --git a/source4/lib/events/events_epoll.c b/source4/lib/events/events_epoll.c index 07e66154fc..c781bd99ae 100644 --- a/source4/lib/events/events_epoll.c +++ b/source4/lib/events/events_epoll.c @@ -20,13 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#if _SAMBA_BUILD_ -#include "includes.h" -#include "lib/util/dlinklist.h" -#else #include "replace.h" -#include "events_util.h" -#endif #include "system/filesys.h" #include "system/network.h" #include "events.h" @@ -63,9 +57,8 @@ struct epoll_event_context { */ static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason) { -#if _SAMBA_BUILD_ - DEBUG(0,("%s (%s) - calling abort()\n", reason, strerror(errno))); -#endif + ev_debug(epoll_ev->ev, EV_DEBUG_FATAL, + "%s (%s) - calling abort()\n", reason, strerror(errno)); abort(); } @@ -122,7 +115,8 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) close(epoll_ev->epoll_fd); epoll_ev->epoll_fd = epoll_create(64); if (epoll_ev->epoll_fd == -1) { - DEBUG(0,("Failed to recreate epoll handle after fork\n")); + ev_debug(epoll_ev->ev, EV_DEBUG_FATAL, + "Failed to recreate epoll handle after fork\n"); return; } epoll_ev->pid = getpid(); @@ -181,7 +175,9 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct fd_even event.events = epoll_map_flags(fde->flags); event.data.ptr = fde; if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event) != 0) { - DEBUG(0,("epoll_del_event failed! probable early close bug (%s)\n", strerror(errno))); + ev_debug(epoll_ev->ev, EV_DEBUG_FATAL, + "epoll_del_event failed! probable early close bug (%s)\n", + strerror(errno)); } fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; } @@ -443,7 +439,7 @@ static int epoll_event_loop_once(struct event_context *ev) struct timeval tval; tval = common_event_loop_timer_delay(ev); - if (timeval_is_zero(&tval)) { + if (ev_timeval_is_zero(&tval)) { return 0; } @@ -483,13 +479,3 @@ bool events_epoll_init(void) { return event_register_backend("epoll", &epoll_event_ops); } - -#if _SAMBA_BUILD_ -NTSTATUS s4_events_epoll_init(void) -{ - if (!events_epoll_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} -#endif diff --git a/source4/lib/events/events_internal.h b/source4/lib/events/events_internal.h index d8c14ead95..78df98a1fe 100644 --- a/source4/lib/events/events_internal.h +++ b/source4/lib/events/events_internal.h @@ -91,10 +91,27 @@ struct signal_event { int sa_flags; }; +/* DEBUG */ +enum ev_debug_level {EV_DEBUG_FATAL, EV_DEBUG_ERROR, + EV_DEBUG_WARNING, EV_DEBUG_TRACE}; + +struct ev_debug_ops { + void (*debug)(void *context, enum ev_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + void *context; +}; + +int ev_set_debug(struct event_context *ev, + void (*debug)(void *context, enum ev_debug_level level, + const char *fmt, va_list ap), + void *context); +int ev_set_debug_stderr(struct event_context *ev); +void ev_debug(struct event_context *ev, enum ev_debug_level level, const char *fmt, ...); + /* aio event is private to the aio backend */ struct aio_event; -struct event_context { +struct event_context { /* the specific events implementation */ const struct event_ops *ops; @@ -109,11 +126,15 @@ struct event_context { /* pipe hack used with signal handlers */ struct fd_event *pipe_fde; + + /* debugging operations */ + struct ev_debug_ops debug_ops; }; bool event_register_backend(const char *name, const struct event_ops *ops); +bool ev_timeval_is_zero(const struct timeval *tv); struct timed_event *common_event_add_timed(struct event_context *, TALLOC_CTX *, struct timeval, event_timed_handler_t, void *); struct timeval common_event_loop_timer_delay(struct event_context *); @@ -126,3 +147,14 @@ struct signal_event *common_event_add_signal(struct event_context *ev, void *private_data); int common_event_check_signal(struct event_context *ev); + +bool events_standard_init(void); +bool events_select_init(void); +#if HAVE_EVENTS_EPOLL +bool events_epoll_init(void); +#endif +#if HAVE_LINUX_AIO +bool events_aio_init(void); +#endif + +#include "events_util.h" diff --git a/source4/lib/events/events_liboop.c b/source4/lib/events/events_liboop.c index 946c3888c1..339297a3cf 100644 --- a/source4/lib/events/events_liboop.c +++ b/source4/lib/events/events_liboop.c @@ -19,9 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "includes.h" -#include "lib/events/events.h" -#include "lib/events/events_internal.h" +#include "events.h" +#include "events_internal.h" #include <oop.h> diff --git a/source4/lib/events/events_s4.c b/source4/lib/events/events_s4.c new file mode 100644 index 0000000000..edf92dba22 --- /dev/null +++ b/source4/lib/events/events_s4.c @@ -0,0 +1,57 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "events.h" +#include "events_internal.h" + +NTSTATUS s4_events_standard_init(void) +{ + if (!events_standard_init()) { + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} + +NTSTATUS s4_events_select_init(void) +{ + if (!events_select_init()) { + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} + +#if HAVE_EVENTS_EPOLL +NTSTATUS s4_events_epoll_init(void) +{ + if (!events_epoll_init()) { + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} +#endif + +#if HAVE_LINUX_AIO +NTSTATUS s4_events_aio_init(void) +{ + if (!events_aio_init()) { + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} +#endif diff --git a/source4/lib/events/events_select.c b/source4/lib/events/events_select.c index 16fff71e4a..9e97d2b39f 100644 --- a/source4/lib/events/events_select.c +++ b/source4/lib/events/events_select.c @@ -23,13 +23,7 @@ */ -#if _SAMBA_BUILD_ -#include "includes.h" -#include "lib/util/dlinklist.h" -#else #include "replace.h" -#include "events_util.h" -#endif #include "system/filesys.h" #include "system/select.h" #include "events.h" @@ -221,9 +215,8 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru made readable and that should have removed the event, so this must be a bug. This is a fatal error. */ -#if _SAMBA_BUILD_ - DEBUG(0,("ERROR: EBADF on select_event_loop_once\n")); -#endif + ev_debug(select_ev->ev, EV_DEBUG_FATAL, + "ERROR: EBADF on select_event_loop_once\n"); select_ev->exit_code = EBADF; return -1; } @@ -265,7 +258,7 @@ static int select_event_loop_once(struct event_context *ev) struct timeval tval; tval = common_event_loop_timer_delay(ev); - if (timeval_is_zero(&tval)) { + if (ev_timeval_is_zero(&tval)) { return 0; } @@ -306,12 +299,3 @@ bool events_select_init(void) return event_register_backend("select", &select_event_ops); } -#if _SAMBA_BUILD_ -_PUBLIC_ NTSTATUS s4_events_select_init(void) -{ - if (!events_select_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} -#endif diff --git a/source4/lib/events/events_signal.c b/source4/lib/events/events_signal.c index 7128612fb0..5c74c47edd 100644 --- a/source4/lib/events/events_signal.c +++ b/source4/lib/events/events_signal.c @@ -19,14 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#if _SAMBA_BUILD_ -#include "includes.h" -#include "lib/util/dlinklist.h" -#else #include <signal.h> #include "replace.h" -#include "events_util.h" -#endif #include "system/filesys.h" #include "system/select.h" #include "events.h" @@ -222,8 +216,8 @@ struct signal_event *common_event_add_signal(struct event_context *ev, if (sig_state->pipe_hack[0] == 0 && sig_state->pipe_hack[1] == 0) { pipe(sig_state->pipe_hack); - set_blocking(sig_state->pipe_hack[0], false); - set_blocking(sig_state->pipe_hack[1], false); + ev_set_blocking(sig_state->pipe_hack[0], false); + ev_set_blocking(sig_state->pipe_hack[1], false); } ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0], EVENT_FD_READ, signal_pipe_handler, NULL); diff --git a/source4/lib/events/events_standard.c b/source4/lib/events/events_standard.c index 4e41c42206..fbf83897c8 100644 --- a/source4/lib/events/events_standard.c +++ b/source4/lib/events/events_standard.c @@ -27,13 +27,7 @@ at runtime we fallback to select() */ -#if _SAMBA_BUILD_ -#include "includes.h" -#include "lib/util/dlinklist.h" -#else #include "replace.h" -#include "events_util.h" -#endif #include "system/filesys.h" #include "system/network.h" #include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */ @@ -76,7 +70,9 @@ struct std_event_context { */ static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason) { - DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno))); + ev_debug(std_ev->ev, EV_DEBUG_FATAL, + "%s (%s) - falling back to select()\n", + reason, strerror(errno)); close(std_ev->epoll_fd); std_ev->epoll_fd = -1; talloc_set_destructor(std_ev, NULL); @@ -133,7 +129,8 @@ static void epoll_check_reopen(struct std_event_context *std_ev) close(std_ev->epoll_fd); std_ev->epoll_fd = epoll_create(64); if (std_ev->epoll_fd == -1) { - DEBUG(0,("Failed to recreate epoll handle after fork\n")); + ev_debug(std_ev->ev, EV_DEBUG_FATAL, + "Failed to recreate epoll handle after fork\n"); return; } std_ev->pid = getpid(); @@ -516,7 +513,8 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva made readable and that should have removed the event, so this must be a bug. This is a fatal error. */ - DEBUG(0,("ERROR: EBADF on std_event_loop_once\n")); + ev_debug(std_ev->ev, EV_DEBUG_FATAL, + "ERROR: EBADF on std_event_loop_once\n"); std_ev->exit_code = EBADF; return -1; } @@ -558,7 +556,7 @@ static int std_event_loop_once(struct event_context *ev) struct timeval tval; tval = common_event_loop_timer_delay(ev); - if (timeval_is_zero(&tval)) { + if (ev_timeval_is_zero(&tval)) { return 0; } @@ -606,12 +604,3 @@ bool events_standard_init(void) return event_register_backend("standard", &std_event_ops); } -#if _SAMBA_BUILD_ -_PUBLIC_ NTSTATUS s4_events_standard_init(void) -{ - if (!events_standard_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} -#endif diff --git a/source4/lib/events/events_timed.c b/source4/lib/events/events_timed.c index 79e4cde795..c81825bf92 100644 --- a/source4/lib/events/events_timed.c +++ b/source4/lib/events/events_timed.c @@ -20,18 +20,91 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#if _SAMBA_BUILD_ -#include "includes.h" -#include "lib/util/dlinklist.h" -#else +#include <sys/time.h> +#include <time.h> #include "replace.h" -#include "events_util.h" -#endif #include "system/filesys.h" #include "system/select.h" #include "events.h" #include "events_internal.h" +/** + compare two timeval structures. + Return -1 if tv1 < tv2 + Return 0 if tv1 == tv2 + Return 1 if tv1 > tv2 +*/ +static int ev_timeval_compare(const struct timeval *tv1, const struct timeval *tv2) +{ + if (tv1->tv_sec > tv2->tv_sec) return 1; + if (tv1->tv_sec < tv2->tv_sec) return -1; + if (tv1->tv_usec > tv2->tv_usec) return 1; + if (tv1->tv_usec < tv2->tv_usec) return -1; + return 0; +} + +/** + return a zero timeval +*/ +static struct timeval ev_timeval_zero(void) +{ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + return tv; +} + +/** + return a timeval for the current time +*/ +static struct timeval ev_timeval_current(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv; +} + +/** + return a timeval struct with the given elements +*/ +static struct timeval ev_timeval_set(uint32_t secs, uint32_t usecs) +{ + struct timeval tv; + tv.tv_sec = secs; + tv.tv_usec = usecs; + return tv; +} + +/** + return the difference between two timevals as a timeval + if tv1 comes after tv2, then return a zero timeval + (this is *tv2 - *tv1) +*/ +static struct timeval ev_timeval_until(const struct timeval *tv1, + const struct timeval *tv2) +{ + struct timeval t; + if (ev_timeval_compare(tv1, tv2) >= 0) { + return ev_timeval_zero(); + } + t.tv_sec = tv2->tv_sec - tv1->tv_sec; + if (tv1->tv_usec > tv2->tv_usec) { + t.tv_sec--; + t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); + } else { + t.tv_usec = tv2->tv_usec - tv1->tv_usec; + } + return t; +} + +/** + return true if a timeval is zero +*/ +bool ev_timeval_is_zero(const struct timeval *tv) +{ + return tv->tv_sec == 0 && tv->tv_usec == 0; +} + /* destroy a timed event */ @@ -72,7 +145,7 @@ struct timed_event *common_event_add_timed(struct event_context *ev, TALLOC_CTX last_te = NULL; for (cur_te = ev->timed_events; cur_te; cur_te = cur_te->next) { /* if the new event comes before the current one break */ - if (timeval_compare(&te->next_event, &cur_te->next_event) < 0) { + if (ev_timeval_compare(&te->next_event, &cur_te->next_event) < 0) { break; } @@ -94,14 +167,14 @@ struct timed_event *common_event_add_timed(struct event_context *ev, TALLOC_CTX */ struct timeval common_event_loop_timer_delay(struct event_context *ev) { - struct timeval current_time = timeval_zero(); + struct timeval current_time = ev_timeval_zero(); struct timed_event *te = ev->timed_events; if (!te) { /* have a default tick time of 30 seconds. This guarantees that code that uses its own timeout checking will be able to proceeed eventually */ - return timeval_set(30, 0); + return ev_timeval_set(30, 0); } /* @@ -113,13 +186,13 @@ struct timeval common_event_loop_timer_delay(struct event_context *ev) * if there's a delay till the next timed event, we're done * with just returning the delay */ - if (!timeval_is_zero(&te->next_event)) { + if (!ev_timeval_is_zero(&te->next_event)) { struct timeval delay; - current_time = timeval_current(); + current_time = ev_timeval_current(); - delay = timeval_until(¤t_time, &te->next_event); - if (!timeval_is_zero(&delay)) { + delay = ev_timeval_until(¤t_time, &te->next_event); + if (!ev_timeval_is_zero(&delay)) { return delay; } } @@ -151,6 +224,6 @@ struct timeval common_event_loop_timer_delay(struct event_context *ev) talloc_free(te); - return timeval_zero(); + return ev_timeval_zero(); } diff --git a/source4/lib/events/events_util.c b/source4/lib/events/events_util.c index 74e11473f3..93f6492560 100644 --- a/source4/lib/events/events_util.c +++ b/source4/lib/events/events_util.c @@ -20,6 +20,9 @@ #include "replace.h" #include "talloc.h" +#include "events.h" +#include "events_internal.h" +#include <fcntl.h> /** return the number of elements in a string list @@ -34,7 +37,7 @@ static size_t str_list_length(const char **list) /** add an entry to a string list */ -const char **str_list_add(const char **list, const char *s) +const char **ev_str_list_add(const char **list, const char *s) { size_t len = str_list_length(list); const char **ret; @@ -50,80 +53,33 @@ const char **str_list_add(const char **list, const char *s) return ret; } -/** - compare two timeval structures. - Return -1 if tv1 < tv2 - Return 0 if tv1 == tv2 - Return 1 if tv1 > tv2 -*/ -static int timeval_compare(const struct timeval *tv1, const struct timeval *tv2) -{ - if (tv1->tv_sec > tv2->tv_sec) return 1; - if (tv1->tv_sec < tv2->tv_sec) return -1; - if (tv1->tv_usec > tv2->tv_usec) return 1; - if (tv1->tv_usec < tv2->tv_usec) return -1; - return 0; -} /** - return a zero timeval -*/ -struct timeval timeval_zero(void) -{ - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - return tv; -} + Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, + else + if SYSV use O_NDELAY + if BSD use FNDELAY +**/ -/** - return true if a timeval is zero -*/ -bool timeval_is_zero(const struct timeval *tv) +int ev_set_blocking(int fd, bool set) { - return tv->tv_sec == 0 && tv->tv_usec == 0; + int val; +#ifdef O_NONBLOCK +#define FLAG_TO_SET O_NONBLOCK +#else +#ifdef SYSV +#define FLAG_TO_SET O_NDELAY +#else /* BSD */ +#define FLAG_TO_SET FNDELAY +#endif +#endif + + if((val = fcntl(fd, F_GETFL, 0)) == -1) + return -1; + if(set) /* Turn blocking on - ie. clear nonblock flag */ + val &= ~FLAG_TO_SET; + else + val |= FLAG_TO_SET; + return fcntl( fd, F_SETFL, val); +#undef FLAG_TO_SET } - -/** - return a timeval for the current time -*/ -struct timeval timeval_current(void) -{ - struct timeval tv; - GetTimeOfDay(&tv); - return tv; -} - -/** - return a timeval struct with the given elements -*/ -struct timeval timeval_set(uint32_t secs, uint32_t usecs) -{ - struct timeval tv; - tv.tv_sec = secs; - tv.tv_usec = usecs; - return tv; -} - -/** - return the difference between two timevals as a timeval - if tv1 comes after tv2, then return a zero timeval - (this is *tv2 - *tv1) -*/ -struct timeval timeval_until(const struct timeval *tv1, - const struct timeval *tv2) -{ - struct timeval t; - if (timeval_compare(tv1, tv2) >= 0) { - return timeval_zero(); - } - t.tv_sec = tv2->tv_sec - tv1->tv_sec; - if (tv1->tv_usec > tv2->tv_usec) { - t.tv_sec--; - t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); - } else { - t.tv_usec = tv2->tv_usec - tv1->tv_usec; - } - return t; -} - diff --git a/source4/lib/events/events_util.h b/source4/lib/events/events_util.h index 401df891a5..052b302aae 100644 --- a/source4/lib/events/events_util.h +++ b/source4/lib/events/events_util.h @@ -113,11 +113,5 @@ do { \ #endif /* _DLINKLIST_H */ -const char **str_list_add(const char **list, const char *s); -struct timeval timeval_zero(void); -bool timeval_is_zero(const struct timeval *tv); -struct timeval timeval_current(void); -struct timeval timeval_set(uint32_t secs, uint32_t usecs); -struct timeval timeval_until(const struct timeval *tv1, - const struct timeval *tv2); - +const char **ev_str_list_add(const char **list, const char *s); +int ev_set_blocking(int fd, bool set); diff --git a/source4/lib/events/libevents.m4 b/source4/lib/events/libevents.m4 index 483ab861fb..be3f1bb638 100644 --- a/source4/lib/events/libevents.m4 +++ b/source4/lib/events/libevents.m4 @@ -13,16 +13,34 @@ if test x"$eventsdir" = "x"; then AC_MSG_ERROR([cannot find libevents source in $eventspaths]) fi -EVENTS_OBJ="events.o events_select.o events_signal.o events_timed.o events_standard.o events_util.o" -AC_SUBST(LIBREPLACEOBJ) +EVENTS_OBJ="events.o events_select.o events_signal.o events_timed.o events_standard.o events_debug.o events_util.o" +SMB_ENABLE(EVENTS_EPOLL, NO) +SMB_ENABLE(EVENTS_AIO, NO) AC_CHECK_HEADERS(sys/epoll.h) AC_CHECK_FUNCS(epoll_create) - if test x"$ac_cv_header_sys_epoll_h" = x"yes" -a x"$ac_cv_func_epoll_create" = x"yes"; then EVENTS_OBJ="$EVENTS_OBJ events_epoll.o" + SMB_ENABLE(EVENTS_EPOLL,YES) AC_DEFINE(HAVE_EVENTS_EPOLL, 1, [Whether epoll available]) + + # check for native Linux AIO interface + AC_CHECK_HEADERS(libaio.h) + AC_CHECK_LIB_EXT(aio, AIO_LIBS, io_getevents) + if test x"$ac_cv_header_libaio_h" = x"yes" -a x"$ac_cv_lib_ext_aio_io_getevents" = x"yes";then + EVENTS_OBJ="$EVENTS_OBJ events_aio.o" + SMB_ENABLE(EVENTS_AIO,YES) + AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available]) + fi fi AC_SUBST(EVENTS_OBJ) +SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS) + +EVENTS_CFLAGS="-I$eventsdir" +AC_SUBST(EVENTS_CFLAGS) + +EVENTS_LIBS="" +AC_SUBST(EVENTS_LIBS) + diff --git a/source4/lib/events/rules.mk b/source4/lib/events/rules.mk new file mode 100644 index 0000000000..cfe548039b --- /dev/null +++ b/source4/lib/events/rules.mk @@ -0,0 +1,21 @@ +.SUFFIXES: .i _wrap.c + +.i_wrap.c: + $(SWIG) -O -Wall -python -keyword $< + +showflags:: + @echo 'libevents will be compiled with flags:' + @echo ' CFLAGS = $(CFLAGS)' + @echo ' CPPFLAGS = $(CPPFLAGS)' + @echo ' LDFLAGS = $(LDFLAGS)' + @echo ' LIBS = $(LIBS)' + +.SUFFIXES: .c .o + +.c.o: + @echo Compiling $*.c + @mkdir -p `dirname $@` + @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@ + +distclean:: + rm -f *~ */*~ diff --git a/source4/lib/ldb/external/libevents.m4 b/source4/lib/ldb/external/libevents.m4 new file mode 100644 index 0000000000..f0f80e9d8e --- /dev/null +++ b/source4/lib/ldb/external/libevents.m4 @@ -0,0 +1,4 @@ +m4_include(pkg.m4) +EVENTS_OBJ="" +AC_SUBST(EVENTS_OBJ) +PKG_CHECK_MODULES(EVENTS, events) |