commit - f6e729443e6f1ef72d5687828bfe2bb327d552ac
commit + 147de9dfa9aea84f7b7cd0eded7a0f07ba36ea06
blob - ee45da37c8da31c6603c1ccefe4f5b50afa78755
blob + 2381916b36d4185c91f0deba1f088c3c7c7154bd
--- configure.in
+++ configure.in
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
-# $Id: configure.in,v 1.121 2006/09/09 17:07:39 fw Exp $
+# $Id: configure.in,v 1.122 2006/09/16 15:00:09 fw Exp $
#
# -- Initialisation --
x_io_backend=select
+AC_ARG_WITH(poll,
+ [ --without-poll disable poll support (autodetected by default)],
+ [ if test "$withval" != "no"; then
+ if test "$withval" != "yes"; then
+ CFLAGS="-I$withval/include $CFLAGS"
+ CPPFLAGS="-I$withval/include $CPPFLAGS"
+ LDFLAGS="-L$withval/lib $LDFLAGS"
+ fi
+ AC_CHECK_FUNCS(poll, x_io_backend=poll,
+ AC_MSG_ERROR([Can't enable poll support!])
+ )
+ fi
+ ],
+ [
+ AC_CHECK_FUNCS(poll, x_io_backend=poll)
+ ]
+)
+
+
AC_ARG_WITH(epoll,
[ --without-epoll disable epoll support (autodetected by default)],
[ if test "$withval" != "no"; then
]
)
+
AC_ARG_WITH(kqueue,
[ --without-kqueue disable kqueue support (autodetected by default)],
[ if test "$withval" != "no"; then
blob - 39b994b22fb67b19d41f52339e9d3f8f300ead94
blob + 9633f6cedf6eeaf7003ad0ee45abc3b1e3eaa395
--- src/ngircd/io.c
+++ src/ngircd/io.c
#include "portab.h"
-static char UNUSED id[] = "$Id: io.c,v 1.17 2006/09/16 14:49:26 fw Exp $";
+static char UNUSED id[] = "$Id: io.c,v 1.18 2006/09/16 15:00:10 fw Exp $";
#include <assert.h>
#include <stdlib.h>
# ifdef HAVE_KQUEUE
#define IO_USE_KQUEUE 1
# else
+# ifdef HAVE_POLL
+#define IO_USE_POLL 1
+# else
#define IO_USE_SELECT 1
+# endif /* HAVE_POLL */
# endif /* HAVE_KQUEUE */
#endif /* HAVE_EPOLL_CREATE */
static bool io_event_change_kqueue(int, short, const int action);
#endif
+#ifdef IO_USE_POLL
+#include <poll.h>
+static array pollfds;
+static int poll_maxfd;
+
+static bool io_event_change_poll(int fd, short what);
+#endif
+
#ifdef IO_USE_SELECT
#include "defines.h" /* for conn.h */
#include "conn.h" /* for CONN_IDX (needed by resolve.h) */
}
+#ifdef IO_USE_POLL
+static bool
+io_library_init_poll(unsigned int eventsize)
+{
+ struct pollfd *p;
+ array_init(&pollfds);
+ poll_maxfd = 0;
+ Log(LOG_INFO, "IO subsystem: poll (initial maxfd %u).",
+ eventsize);
+ p = array_alloc(&pollfds, sizeof(struct pollfd), eventsize);
+ if (p) {
+ unsigned i;
+ p = array_start(&pollfds);
+ for (i = 0; i < eventsize; i++)
+ p[i].fd = -1;
+
+ library_initialized = true;
+ }
+ return p != NULL;
+}
+#endif
+
+
#ifdef IO_USE_SELECT
static bool
io_library_init_select(unsigned int eventsize)
#ifdef IO_USE_KQUEUE
return io_library_init_kqueue(eventsize);
#endif
+#ifdef IO_USE_POLL
+ return io_library_init_poll(eventsize);
+#endif
#ifdef IO_USE_SELECT
return io_library_init_select(eventsize);
#endif
i->callback = cbfunc;
i->what = 0;
+#ifdef IO_USE_POLL
+ ret = io_event_change_poll(fd, what);
+#endif
#ifdef IO_USE_EPOLL
ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD);
#endif
}
+#ifdef IO_USE_POLL
+static bool
+io_event_change_poll(int fd, short what)
+{
+ struct pollfd *p;
+ short events = 0;
+
+ if (what & IO_WANTREAD)
+ events = POLLIN | POLLPRI;
+ if (what & IO_WANTWRITE)
+ events |= POLLOUT;
+
+ p = array_alloc(&pollfds, sizeof *p, fd);
+ if (p) {
+ p->events = events;
+ p->fd = fd;
+ if (fd > poll_maxfd)
+ poll_maxfd = fd;
+ }
+ return p != NULL;
+}
+#endif
+
#ifdef IO_USE_EPOLL
static bool
io_event_change_epoll(int fd, short what, const int action)
#ifdef IO_USE_KQUEUE
return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE);
#endif
+#ifdef IO_USE_POLL
+ return io_event_change_poll(fd, i->what);
+#endif
#ifdef IO_USE_SELECT
if (fd > select_maxfd)
select_maxfd = fd;
flags |= O_NONBLOCK;
return fcntl(fd, F_SETFL, flags) == 0;
+}
+
+
+#ifdef IO_USE_POLL
+static void
+io_close_poll(int fd)
+{
+ struct pollfd *p;
+ p = array_get(&pollfds, sizeof *p, fd);
+ if (!p) return;
+
+ p->fd = -1;
+ if (fd == poll_maxfd) {
+ while (poll_maxfd > 0) {
+ --poll_maxfd;
+ p = array_get(&pollfds, sizeof *p, poll_maxfd);
+ if (p && p->fd >= 0)
+ break;
+ }
+ }
}
+#else
+static inline void io_close_poll(int UNUSED x) { /* NOTHING */ }
+#endif
#ifdef IO_USE_SELECT
}
#endif
+ io_close_poll(fd);
io_close_select(fd);
#ifdef IO_USE_EPOLL
i->what &= ~what;
+#ifdef IO_USE_POLL
+ return io_event_change_poll(fd, i->what);
+#endif
#ifdef IO_USE_EPOLL
return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
#endif
fds_ready--;
}
if (what)
+ io_docallback(i, what);
+ if (fds_ready <= 0)
+ break;
+ }
+
+ return ret;
+}
+#endif
+
+
+#ifdef IO_USE_POLL
+static int
+io_dispatch_poll(struct timeval *tv)
+{
+ time_t sec = tv->tv_sec * 1000;
+ int i, ret, timeout = tv->tv_usec + sec;
+ int fds_ready;
+ short what;
+ struct pollfd *p = array_start(&pollfds);
+
+ if (timeout < 0)
+ timeout = 1000;
+
+ ret = poll(p, poll_maxfd + 1, timeout);
+ if (ret <= 0)
+ return ret;
+
+ fds_ready = ret;
+ for (i=0; i <= poll_maxfd; i++) {
+ what = 0;
+ if (p[i].revents & (POLLIN|POLLPRI))
+ what = IO_WANTREAD;
+
+ if (p[i].revents & POLLOUT)
+ what |= IO_WANTWRITE;
+
+ if (p[i].revents && !what) {
+ /* other flag is set, probably POLLERR */
+ what = IO_ERROR;
+ }
+ if (what) {
+ fds_ready--;
io_docallback(i, what);
+ }
if (fds_ready <= 0)
break;
}
#ifdef IO_USE_KQUEUE
return io_dispatch_kqueue(tv);
#endif
+#ifdef IO_USE_POLL
+ return io_dispatch_poll(tv);
+#endif
#ifdef IO_USE_EPOLL
return io_dispatch_epoll(tv);
#endif