Add epoll_* ioset backend.
authorMichael Poole <mdpoole@troilus.org>
Fri, 22 Sep 2006 02:45:20 +0000 (02:45 +0000)
committerMichael Poole <mdpoole@troilus.org>
Fri, 22 Sep 2006 02:45:20 +0000 (02:45 +0000)
configure.in: Check for epoll_create(); demote select() from being required.

src/Makefile.am (EXTRA_srvx_SOURCES): Add ioset-epoll.c.

src/ioset-epoll.c: New file.
git-archimport-id: srvx@srvx.net--2006/srvx--devo--1.3--patch-39

ChangeLog
configure.in
src/Makefile.am
src/ioset-epoll.c [new file with mode: 0644]

index 1ae72566636714b50cd8729863c6871c6dda2e31..c9690b3df92ac0ffec04088c41e59b3f6a65db75 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,26 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2006/srvx--devo--1.3
 #
 
+2006-09-22 02:45:20 GMT        Michael Poole <mdpoole@troilus.org>     patch-39
+
+    Summary:
+      Add epoll_* ioset backend.
+    Revision:
+      srvx--devo--1.3--patch-39
+
+    configure.in: Check for epoll_create(); demote select() from being required.
+    
+    src/Makefile.am (EXTRA_srvx_SOURCES): Add ioset-epoll.c.
+    
+    src/ioset-epoll.c: New file.
+
+    new files:
+     src/.arch-ids/ioset-epoll.c.id src/ioset-epoll.c
+
+    modified files:
+     ChangeLog configure.in src/Makefile.am
+
+
 2006-09-22 02:38:21 GMT        Michael Poole <mdpoole@troilus.org>     patch-38
 
     Summary:
index dd6474bb110e9b5d7bf99967bbd00f11c20f34e1..01a9e3f1519239e6c3751e8f9911d4c38b3fca64 100644 (file)
@@ -69,7 +69,7 @@ AC_HEADER_TIME
 AC_STRUCT_TM
 
 dnl Would rather not bail on headers, BSD has alot of the functions elsewhere. -Jedi
-AC_CHECK_HEADERS(fcntl.h malloc.h netdb.h arpa/inet.h netinet/in.h sys/resource.h sys/timeb.h sys/times.h sys/param.h sys/socket.h sys/time.h sys/types.h sys/wait.h unistd.h getopt.h memory.h regex.h arpa/inet.h sys/mman.h sys/stat.h dirent.h,,)
+AC_CHECK_HEADERS(fcntl.h malloc.h netdb.h arpa/inet.h netinet/in.h sys/resource.h sys/timeb.h sys/times.h sys/param.h sys/socket.h sys/time.h sys/types.h sys/wait.h unistd.h getopt.h memory.h regex.h arpa/inet.h sys/mman.h sys/stat.h dirent.h sys/epoll.h,,)
 
 dnl portability stuff, hurray! -Jedi
 AC_CHECK_MEMBER([struct sockaddr.sa_len],
@@ -87,10 +87,10 @@ if test $ac_cv_func_gettimeofday = no; then
 fi
 
 dnl We have fallbacks in case these are missing, so just check for them.
-AC_CHECK_FUNCS(freeaddrinfo getaddrinfo getnameinfo getpagesize memcpy memset strdup strerror strsignal localtime_r setrlimit getopt getopt_long regcomp regexec regfree sysconf inet_aton,,)
+AC_CHECK_FUNCS(freeaddrinfo getaddrinfo getnameinfo getpagesize memcpy memset strdup strerror strsignal localtime_r setrlimit getopt getopt_long regcomp regexec regfree sysconf inet_aton epoll_create select,,)
 
 dnl Check for absolutely required library functions.
-AC_CHECK_FUNCS(select socket strcspn strspn strtod strtoul,,AC_MSG_ERROR([a required function was not found.  srvx build will fail.]))
+AC_CHECK_FUNCS(socket strcspn strspn strtod strtoul,,AC_MSG_ERROR([a required function was not found.  srvx build will fail.]))
 
 dnl Check for functions (and how to get them).
 AC_FUNC_ALLOCA
@@ -250,8 +250,22 @@ if test "x$ac_cv_func_select" = xyes ; then
   IOMUXES="$IOMUXES select"
 fi
 
+AC_ARG_WITH([epoll],
+[  --without-epoll         Disables the epoll_*() I/O backend],
+[],
+[withval="$ac_cv_func_epoll_create"])
+if test "x$withval" = xyes ; then
+  AC_DEFINE(WITH_IOSET_EPOLL, 1, [Define if using the epoll I/O backend])
+  MODULE_OBJS="$MODULE_OBJS ioset-epoll.\$(OBJEXT)"
+  IOMUXES="$IOMUXES epoll"
+fi
+
 IOMUXES=`echo $IOMUXES | sed 's/^ +//'`
-AC_MSG_RESULT($IOMUXES)
+if test "x$IOMUXES" = "x" ; then
+  AC_MSG_ERROR([No supported I/O multiplexing backend found])
+else
+  AC_MSG_RESULT($IOMUXES)
+fi
 
 AC_ARG_WITH(getopt,
 [  --without-getopt        Disables building of the GNU getopt library],
index 37df3cdf484ce033ec7e1d2d0e68f96c1cd7b7ca..290d948c0a03ef56f794102d795c5e4fbdbd31a9 100644 (file)
@@ -37,6 +37,7 @@ endif
 EXTRA_srvx_SOURCES = \
        alloc-slab.c \
        alloc-srvx.c \
+       ioset-epoll.c \
        ioset-select.c \
        proto-bahamut.c \
        proto-common.c \
diff --git a/src/ioset-epoll.c b/src/ioset-epoll.c
new file mode 100644 (file)
index 0000000..e09f83f
--- /dev/null
@@ -0,0 +1,129 @@
+/* ioset epoll_*() backend for srvx
+ * Copyright 2006 srvx Development Team
+ *
+ * This file is part of srvx.
+ *
+ * srvx 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 2 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 srvx; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+
+#include "ioset-impl.h"
+#include "common.h"
+#include "log.h"
+
+#ifdef HAVE_SYS_EPOLL_H
+# include <sys/epoll.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+extern int clock_skew;
+static int epoll_fd;
+
+static int
+ioset_epoll_init(void)
+{
+    epoll_fd = epoll_create(1024);
+    if (epoll_fd < 0)
+        return 0;
+    return 1;
+}
+
+static int
+ioset_epoll_events(struct io_fd *fd)
+{
+    return EPOLLHUP
+        | (fd_wants_reads(fd) ? EPOLLIN : 0)
+        | (fd_wants_writes(fd) ? EPOLLOUT : 0)
+        ;
+}
+
+static void
+ioset_epoll_add(struct io_fd *fd)
+{
+    struct epoll_event evt;
+    int res;
+
+    evt.events = ioset_epoll_events(fd);
+    evt.data.ptr = fd;
+    res = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd->fd, &evt);
+    if (res < 0)
+        log_module(MAIN_LOG, LOG_ERROR, "Unable to add fd %d to epoll: %s", fd->fd, strerror(errno));
+}
+
+static void
+ioset_epoll_remove(struct io_fd *fd)
+{
+    static struct epoll_event evt;
+    (void)epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd->fd, &evt);
+}
+
+static void
+ioset_epoll_update(struct io_fd *fd)
+{
+    struct epoll_event evt;
+    int res;
+
+    evt.events = ioset_epoll_events(fd);
+    evt.data.ptr = fd;
+    res = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd->fd, &evt);
+    if (res < 0)
+        log_module(MAIN_LOG, LOG_ERROR, "Unable to modify fd %d for epoll: %s", fd->fd, strerror(errno));
+}
+
+static void
+ioset_epoll_cleanup(void)
+{
+    close(epoll_fd);
+}
+
+static int
+ioset_epoll_loop(struct timeval *timeout)
+{
+    struct epoll_event evts[32];
+    int events;
+    int msec;
+    int res;
+    int ii;
+
+    msec = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : -1;
+
+    res = epoll_wait(epoll_fd, evts, ArrayLength(evts), msec);
+    if (res < 0) {
+        if (errno != EINTR) {
+            log_module(MAIN_LOG, LOG_ERROR, "epoll_wait() error %d: %s", errno, strerror(errno));
+            close_socket();
+        }
+        return 1;
+    }
+
+    for (ii = 0; ii < res; ++ii) {
+        events = evts[ii].events;
+        ioset_events(evts[ii].data.ptr, (events & (EPOLLIN | EPOLLHUP)), (events & EPOLLOUT));
+    }
+
+    return 0;
+}
+
+struct io_engine io_engine_epoll = {
+    .name = "epoll",
+    .init = ioset_epoll_init,
+    .add = ioset_epoll_add,
+    .remove = ioset_epoll_remove,
+    .update = ioset_epoll_update,
+    .loop = ioset_epoll_loop,
+    .cleanup = ioset_epoll_cleanup,
+};