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],
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
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],
--- /dev/null
+/* 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,
+};