]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
- added a EVENT_FD_AUTOCLOSE flag that allows you to tell the event system to close...
authorAndrew Tridgell <tridge@samba.org>
Sat, 5 May 2007 07:17:25 +0000 (17:17 +1000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 5 May 2007 07:17:25 +0000 (17:17 +1000)
- added autoconf rules for automatically building with epoll support

(This used to be ctdb commit 4d113298b26f7163992f2e47429c953bd4f957c9)

ctdb/lib/events/events.c
ctdb/lib/events/events.h
ctdb/lib/events/events_aio.c
ctdb/lib/events/events_epoll.c
ctdb/lib/events/events_liboop.c
ctdb/lib/events/events_select.c
ctdb/lib/events/events_standard.c
ctdb/lib/events/libevents.m4 [new file with mode: 0644]
ctdb/lib/replace/system/select.h

index 3a81b55bd9478e5a1aaf3ab5f8a06e0683151ffc..5b36e70ac056ba2c62248676f3a800ad3a6418b0 100644 (file)
@@ -71,6 +71,8 @@ struct event_ops_list {
 /* list of registered event backends */
 static struct event_ops_list *event_backends;
 
+static char *event_default_backend = NULL;
+
 /*
   register an events backend
 */
@@ -85,6 +87,15 @@ bool event_register_backend(const char *name, const struct event_ops *ops)
        return True;
 }
 
+/*
+  set the default event backend
+ */
+void event_set_default_backend(const char *backend)
+{
+       if (event_default_backend) free(event_default_backend);
+       event_default_backend = strdup(backend);
+}
+
 /*
   initialise backends if not already done
 */
@@ -99,7 +110,15 @@ static void event_backend_init(void)
        run_init_functions(shared_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();
+       }
+#endif
 #endif
 }
 
@@ -169,6 +188,9 @@ struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char
                name = lp_parm_string(-1, "event", "backend");
        }
 #endif
+       if (name == NULL) {
+               name = event_default_backend;
+       }
        if (name == NULL) {
                name = "standard";
        }
@@ -195,6 +217,9 @@ struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
 /*
   add a fd based event
   return NULL on failure (memory allocation error)
+
+  if flags contains EVENT_FD_AUTOCLOSE then the fd will be closed when
+  the returned fd_event context is freed
 */
 struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
                              int fd, uint16_t flags, event_fd_handler_t handler,
index caeb1f013158eeb265a852ef5610627754d7af45..42d67c31bf80d0af501e77aff7bbe98cece05fa2 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef __EVENTS_H__
 #define __EVENTS_H__
 
-#include "lib/talloc/talloc.h"
+#include "talloc/talloc.h"
 #include <stdlib.h>
 
 struct event_context;
@@ -46,6 +46,7 @@ typedef void (*event_aio_handler_t)(struct event_context *, struct aio_event *,
 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);
+void event_set_default_backend(const char *backend);
 
 struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
                              int fd, uint16_t flags, event_fd_handler_t handler,
@@ -79,6 +80,7 @@ struct event_context *event_context_find(TALLOC_CTX *mem_ctx);
 /* bits for file descriptor event flags */
 #define EVENT_FD_READ 1
 #define EVENT_FD_WRITE 2
+#define EVENT_FD_AUTOCLOSE 4
 
 #define EVENT_FD_WRITEABLE(fde) \
        event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
index 9f4e9c561240d561af10233f2a605863dd542ab1..3504df19cb141ae0b778cfd849cc6932ab99df14 100644 (file)
@@ -360,6 +360,11 @@ static int aio_event_fd_destructor(struct fd_event *fde)
 
        epoll_del_event(aio_ev, fde);
 
+       if (fde->flags & EVENT_FD_AUTOCLOSE) {
+               close(fde->fd);
+               fde->fd = -1;
+       }
+
        return 0;
 }
 
index 41a6509e36f9430ce1067304713ecbfc68d7e111..16976977ca3f9634758f8a672521c6c8af795bfd 100644 (file)
@@ -136,7 +136,9 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct fd_even
        ZERO_STRUCT(event);
        event.events = epoll_map_flags(fde->flags);
        event.data.ptr = fde;
-       epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
+       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)));
+       }
        fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
 }
 
@@ -202,7 +204,7 @@ static void epoll_change_event(struct epoll_event_context *epoll_ev, struct fd_e
 static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp)
 {
        int ret, i;
-#define MAXEVENTS 8
+#define MAXEVENTS 32
        struct epoll_event events[MAXEVENTS];
        uint32_t destruction_count = ++epoll_ev->destruction_count;
        int timeout = -1;
@@ -305,6 +307,11 @@ static int epoll_event_fd_destructor(struct fd_event *fde)
 
        epoll_del_event(epoll_ev, fde);
 
+       if (fde->flags & EVENT_FD_AUTOCLOSE) {
+               close(fde->fd);
+               fde->fd = -1;
+       }
+
        return 0;
 }
 
index 96bdafd956d2c39d21e2b9e2257e36b6634a6024..cc9047b4eb551f6b0c41b8e767809eb13ac68843 100644 (file)
@@ -101,6 +101,11 @@ static int oop_event_fd_destructor(struct fd_event *fde)
        if (fde->flags & EVENT_FD_WRITE)
                oop->cancel_fd(oop, fde->fd, OOP_WRITE);
 
+       if (fde->flags & EVENT_FD_AUTOCLOSE) {
+               close(fde->fd);
+               fde->fd = -1;
+       }
+
        return 0;
 }
 
index 291ddbde2b0e2975b155aaebd4c93085acd12948..32efa485cf9f8fe7a00ef415a57abf25fc324877 100644 (file)
@@ -104,6 +104,11 @@ static int select_event_fd_destructor(struct fd_event *fde)
        DLIST_REMOVE(select_ev->fd_events, fde);
        select_ev->destruction_count++;
 
+       if (fde->flags & EVENT_FD_AUTOCLOSE) {
+               close(fde->fd);
+               fde->fd = -1;
+       }
+
        return 0;
 }
 
index 8495ccdec0c256cd9649fa80dd2909495944aa9f..dfad0e66b3a8bf02431832f4d1f95d19f9144956 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "includes.h"
 #include "system/filesys.h"
-#include "system/select.h" /* needed for WITH_EPOLL */
+#include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */
 #include "lib/util/dlinklist.h"
 #include "lib/events/events.h"
 #include "lib/events/events_internal.h"
@@ -61,7 +61,7 @@ struct std_event_context {
 };
 
 /* use epoll if it is available */
-#if WITH_EPOLL
+#if HAVE_EVENTS_EPOLL
 /*
   called when a epoll call fails, and we should fallback
   to using select
@@ -229,15 +229,15 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
                timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
        }
 
-       if (epoll_ev->ev->num_signal_handlers && 
-           common_event_check_signal(epoll_ev->ev)) {
+       if (std_ev->ev->num_signal_handlers && 
+           common_event_check_signal(std_ev->ev)) {
                return 0;
        }
 
        ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
 
-       if (ret == -1 && errno == EINTR && epoll_ev->ev->num_signal_handlers) {
-               if (common_event_check_signal(epoll_ev->ev)) {
+       if (ret == -1 && errno == EINTR && std_ev->ev->num_signal_handlers) {
+               if (common_event_check_signal(std_ev->ev)) {
                        return 0;
                }
        }
@@ -352,6 +352,11 @@ static int std_event_fd_destructor(struct fd_event *fde)
 
        epoll_del_event(std_ev, fde);
 
+       if (fde->flags & EVENT_FD_AUTOCLOSE) {
+               close(fde->fd);
+               fde->fd = -1;
+       }
+
        return 0;
 }
 
diff --git a/ctdb/lib/events/libevents.m4 b/ctdb/lib/events/libevents.m4
new file mode 100644 (file)
index 0000000..99a47dc
--- /dev/null
@@ -0,0 +1,11 @@
+EVENTS_OBJ="lib/events/events.o lib/events/events_select.o lib/events/events_signal.o lib/events/events_timed.o lib/events/events_standard.o"
+
+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 lib/events/events_epoll.o"
+   AC_DEFINE(HAVE_EVENTS_EPOLL, 1, [Whether epoll available])
+fi
+
+AC_SUBST(EVENTS_OBJ)
index 20346259c2760518ba63656da81ebb6332cbc316..465e005349cb199c8b024599393fbcaf363801f3 100644 (file)
 #include <sys/select.h>
 #endif
 
+#ifdef HAVE_SYS_EPOLL_H
+#include <sys/epoll.h>
+#endif
+
 #ifndef SELECT_CAST
 #define SELECT_CAST
 #endif