add support for the poll() interface
This commit is contained in:
parent
f6e729443e
commit
147de9dfa9
22
configure.in
22
configure.in
|
@ -8,7 +8,7 @@
|
|||
# (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 --
|
||||
|
@ -200,6 +200,25 @@ fi
|
|||
|
||||
|
||||
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
|
||||
|
@ -218,6 +237,7 @@ AC_ARG_WITH(epoll,
|
|||
]
|
||||
)
|
||||
|
||||
|
||||
AC_ARG_WITH(kqueue,
|
||||
[ --without-kqueue disable kqueue support (autodetected by default)],
|
||||
[ if test "$withval" != "no"; then
|
||||
|
|
142
src/ngircd/io.c
142
src/ngircd/io.c
|
@ -12,7 +12,7 @@
|
|||
|
||||
#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>
|
||||
|
@ -43,7 +43,11 @@ typedef struct {
|
|||
# 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 */
|
||||
|
||||
|
@ -67,6 +71,14 @@ static int io_dispatch_kqueue(struct timeval *tv);
|
|||
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) */
|
||||
|
@ -98,6 +110,29 @@ io_event_get(int fd)
|
|||
}
|
||||
|
||||
|
||||
#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)
|
||||
|
@ -180,6 +215,9 @@ io_library_init(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
|
||||
|
@ -243,6 +281,9 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
|
|||
|
||||
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
|
||||
|
@ -257,6 +298,29 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
|
|||
}
|
||||
|
||||
|
||||
#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)
|
||||
|
@ -347,6 +411,9 @@ io_event_add(int fd, short what)
|
|||
#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;
|
||||
|
@ -377,6 +444,29 @@ io_setnonblock(int fd)
|
|||
}
|
||||
|
||||
|
||||
#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
|
||||
static void
|
||||
io_close_select(int fd)
|
||||
|
@ -420,6 +510,7 @@ io_close(int fd)
|
|||
}
|
||||
#endif
|
||||
|
||||
io_close_poll(fd);
|
||||
io_close_select(fd);
|
||||
|
||||
#ifdef IO_USE_EPOLL
|
||||
|
@ -444,6 +535,9 @@ io_event_del(int fd, short what)
|
|||
|
||||
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
|
||||
|
@ -500,6 +594,49 @@ io_dispatch_select(struct timeval *tv)
|
|||
#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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef IO_USE_EPOLL
|
||||
static int
|
||||
io_dispatch_epoll(struct timeval *tv)
|
||||
|
@ -616,6 +753,9 @@ io_dispatch(struct timeval *tv)
|
|||
#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
|
||||
|
|
Loading…
Reference in New Issue