Hi,
the attached patch contains these changes:
2005-12-15 22:18 Vaclav Haisman <v.haisman@sh.cvut.cz>
* src/lib/ioloop-kqueue.c: Fix IO_ERROR behaviour.
* src/lib/ioloop-notify-kqueue.c: New file.
* configure.in: Improve kqueue detection and handling. Cleanup.
The configure.in changes that are not related to kqueue are there to make
autoconf 2.59, automake 1.9.6 and libtool 1.5.20 are happy.
The directory change notification is not really well tested because Dovecot
doesn't seem to use it that much.
As per Brad's request I have changed all occurrences of FreeBSD to just BSD.
Vaclav Haisman
-------------- next part --------------
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
<linux/inotify.h> and <linux/inotify-syscalls.h>])
])
+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 <v.haisman@sh.cvut.cz>
*
@@ -16,6 +16,7 @@
#ifdef IOLOOP_KQUEUE
+#include <unistd.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
@@ -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 \
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ioloop-notify-kqueue.c
Type: text/x-csrc
Size: 3416 bytes
Desc: The new file
Url :
http://dovecot.org/pipermail/dovecot/attachments/20051215/b0a8fb4d/ioloop-notify-kqueue.c