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
 #
 
 # 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:
 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_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],
 
 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.
 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.
 
 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
 
 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
 
   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/^ +//'`
 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],
 
 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 \
 EXTRA_srvx_SOURCES = \
        alloc-slab.c \
        alloc-srvx.c \
+       ioset-epoll.c \
        ioset-select.c \
        proto-bahamut.c \
        proto-common.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,
+};