Index: configure.in =================================================================== RCS file: /home/cvs/dovecot/configure.in,v retrieving revision 1.227 diff -u -p -d -r1.227 configure.in --- configure.in 14 Dec 2005 21:34:01 -0000 1.227 +++ configure.in 15 Dec 2005 21:29:09 -0000 @@ -1,25 +1,24 @@ -AC_INIT(dovecot, 1.0.alpha5, [dovecot@dovecot.org]) +AC_PREREQ([2.59]) +AC_INIT([dovecot],[1.0.alpha5],[dovecot@dovecot.org]) AC_CONFIG_SRCDIR([src]) -AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE AC_ISC_POSIX +AC_GNU_SOURCE AC_PROG_CC AC_PROG_CPP AC_HEADER_STDC AC_C_INLINE -AM_PROG_LIBTOOL +AC_PROG_LIBTOOL AM_ICONV -AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h \ +AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h time.h \ sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \ - sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h mntent.h sys/mnttab.h) - -# check posix headers -AC_CHECK_HEADERS(sys/time.h) + sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h mntent.h sys/mnttab.h \ + sys/event.h sys/time.h) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Enable IPv6 support (default)], @@ -54,13 +53,14 @@ AC_ARG_WITH(mem-align, mem_align=8) AC_ARG_WITH(ioloop, -[ --with-ioloop=IOLOOP Specify the I/O loop method to use], +[ --with-ioloop=IOLOOP Specify the I/O loop method to use + (epoll, kqueue, poll; default is poll)], ioloop=$withval, ioloop=) AC_ARG_WITH(notify, [ --with-notify=IOLOOP Specify the file system notification method to use - (dnotify, inotify, none; + (dnotify, inotify, kqueue, none; default dnotify if compilable, otherwise none)], notify=$withval, notify=) @@ -312,7 +312,7 @@ dnl * after -lsocket and -lnsl tests, in AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \ strcasecmp stricmp vsnprintf vsyslog writev pread \ setrlimit setproctitle seteuid setreuid setegid setresgid \ - strtoull strtouq setpriority quotactl getmntent) + strtoull strtouq setpriority quotactl getmntent kqueue kevent) dnl * I/O loop function have_ioloop=no @@ -329,12 +329,17 @@ if test "$ioloop" = "epoll"; then fi if test "$ioloop" = "kqueue"; then - AC_CHECK_FUNC(kqueue, [ - AC_DEFINE(IOLOOP_KQUEUE,, [Implement I/O loop with FreeBSD kqueue()]) - have_ioloop=yes - ], [ + if test "$ac_cv_func_kqueue" != yes ; then + AC_MSG_WARN([kqueue ioloop requested but kqueue() is not available]) ioloop="" - ]) + elif test "$ac_cv_func_kevent" != yes ; then + AC_MSG_WARN([kqueue ioloop requested but kevent() is not available]) + ioloop="" + else + AC_DEFINE(IOLOOP_KQUEUE,, [Implement I/O loop with BSD kqueue()]) + ioloop=kqueue + have_ioloop=yes + fi fi if test "$ioloop" = "" || test "$ioloop" = "poll"; then @@ -401,6 +406,19 @@ elif test "$notify" = "inotify"; then ], [ AC_MSG_ERROR([inotify requested but not available, check for existence of and ]) ]) +elif test "$notify" = "kqueue"; then + dnl * BSD kqueue() notify + if test "$ac_cv_func_kqueue" != yes ; then + AC_MSG_WARN([kqueue notify requested but kqueue() is not available]) + notify="" + elif test "$ac_cv_func_kevent" != yes ; then + AC_MSG_WARN([kqueue notify requested but kevent() is not available]) + notify="" + else + have_notify=kqueue + AC_DEFINE(IOLOOP_NOTIFY_KQUEUE,, + Use BSD kqueue directory changes notificaton) + fi else AC_MSG_ERROR([Unknown notify method: $notify]) fi @@ -1494,6 +1512,7 @@ AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$ CFLAGS="$CFLAGS $EXTRA_CFLAGS" +AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile doc/Makefile Index: src/lib/ioloop-kqueue.c =================================================================== RCS file: /home/cvs/dovecot/src/lib/ioloop-kqueue.c,v retrieving revision 1.1 diff -u -p -d -r1.1 ioloop-kqueue.c --- src/lib/ioloop-kqueue.c 14 Dec 2005 18:51:52 -0000 1.1 +++ src/lib/ioloop-kqueue.c 15 Dec 2005 21:29:09 -0000 @@ -1,5 +1,5 @@ /* - * FreeBSD kqueue() based ioloop handler. + * BSD kqueue() based ioloop handler. * * Copyright (c) 2005 Vaclav Haisman * @@ -16,6 +16,7 @@ #ifdef IOLOOP_KQUEUE +#include #include #include #include @@ -24,6 +25,8 @@ # define INITIAL_BUF_SIZE 128 #endif +#define MASK (IO_READ | IO_WRITE | IO_ERROR) + struct ioloop_handler_context { int kq; size_t evbuf_size; @@ -57,6 +60,7 @@ void io_loop_handler_init(struct ioloop void io_loop_handler_deinit(struct ioloop *ioloop) { + close(ioloop->handler_context->kq); p_free(ioloop->pool, ioloop->handler_context->evbuf); p_free(ioloop->pool, ioloop->handler_context->fds); p_free(ioloop->pool, ioloop->handler_context); @@ -66,8 +70,8 @@ void io_loop_handle_add(struct ioloop *i { struct ioloop_handler_context *ctx = ioloop->handler_context; const int fd = io->fd; - struct kevent ev = {fd, 0, EV_ADD | EV_CLEAR | EV_EOF, 0, 0, NULL}; - enum io_condition condition = io->condition; + struct kevent ev = { fd, 0, EV_ADD | EV_EOF, 0, 0, NULL }; + enum io_condition condition = io->condition & MASK; /* grow ctx->fds array if necessary */ if ((size_t)fd >= ctx->fds_size) { @@ -103,10 +107,10 @@ void io_loop_handle_add(struct ioloop *i void io_loop_handle_remove(struct ioloop *ioloop, struct io *io) { struct ioloop_handler_context *ctx = ioloop->handler_context; + const int fd = io->fd; struct kevent ev = { fd, 0, EV_DELETE, 0, 0, NULL }; struct fdrecord *const fds = ctx->fds; - const int fd = io->fd; - const enum io_condition condition = io->condition; + const enum io_condition condition = io->condition & MASK; i_assert((size_t)fd < ctx->fds_size); i_assert(fds[fd].mode != 0); @@ -160,7 +164,8 @@ void io_loop_handler_run(struct ioloop * struct io *io = ctx->evbuf[i].udata; i_assert(ctx->evbuf[i].ident < ctx->fds_size); - if (ctx->fds[ctx->evbuf[i].ident].mode & IO_ERROR) { + if ((ctx->fds[ctx->evbuf[i].ident].mode & IO_ERROR) + && (ctx->evbuf[i].flags & EV_EOF)) { struct io *errio = ctx->fds[ctx->evbuf[i].ident].errio; t_id = t_push(); @@ -171,8 +176,8 @@ void io_loop_handler_run(struct ioloop * (void *)errio->callback); } } - - if (ctx->fds[ctx->evbuf[i].ident].mode & (IO_WRITE | IO_READ)) { + else if (ctx->fds[ctx->evbuf[i].ident].mode + & (IO_WRITE | IO_READ)) { t_id = t_push(); io->callback(io->context); if (t_pop() != t_id) { @@ -181,6 +186,8 @@ void io_loop_handler_run(struct ioloop * (void *)io->callback); } } + else + i_panic("Unrecognized event"); } } Index: src/lib/Makefile.am =================================================================== RCS file: /home/cvs/dovecot/src/lib/Makefile.am,v retrieving revision 1.56 diff -u -p -d -r1.56 Makefile.am --- src/lib/Makefile.am 14 Dec 2005 18:51:52 -0000 1.56 +++ src/lib/Makefile.am 15 Dec 2005 21:29:09 -0000 @@ -32,6 +32,7 @@ liblib_a_SOURCES = \ ioloop-notify-none.c \ ioloop-notify-dn.c \ ioloop-notify-inotify.c \ + ioloop-notify-kqueue.c \ ioloop-poll.c \ ioloop-select.c \ ioloop-epoll.c \