[dovecot-cvs] dovecot/src/lib ioloop-kqueue.c, 1.2,
1.3 ioloop-notify-kqueue.c, 1.1, 1.2 ioloop.c, 1.31, 1.32
cras at dovecot.org
cras at dovecot.org
Sun Jan 29 12:32:39 EET 2006
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index/dbox dbox-save.c, 1.3,
1.4 dbox-transaction.c, 1.1, 1.2 dbox-uidlist.c, 1.14,
1.15 dbox-uidlist.h, 1.3, 1.4
- Next message: [dovecot-cvs] dovecot/src/lib ioloop-internal.h, 1.15,
1.16 ioloop-notify-dn.c, 1.13, 1.14 ioloop-notify-inotify.c,
1.8, 1.9 ioloop-notify-kqueue.c, 1.2, 1.3 ioloop.c, 1.32, 1.33
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv25217
Modified Files:
ioloop-kqueue.c ioloop-notify-kqueue.c ioloop.c
Log Message:
kqueue updates. Patch by Vaclav Haisman
Index: ioloop-kqueue.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-kqueue.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ioloop-kqueue.c 30 Dec 2005 20:56:05 -0000 1.2
+++ ioloop-kqueue.c 29 Jan 2006 10:32:37 -0000 1.3
@@ -12,11 +12,13 @@
/* @UNSAFE: whole file */
#include "lib.h"
-#include "ioloop-internal.h"
#ifdef IOLOOP_KQUEUE
+#include "fd-close-on-exec.h"
+#include "ioloop-internal.h"
#include <unistd.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
@@ -28,166 +30,182 @@
#define MASK (IO_READ | IO_WRITE | IO_ERROR)
struct ioloop_handler_context {
- int kq;
- size_t evbuf_size;
- struct kevent *evbuf;
+ int kq;
+ size_t evbuf_size;
+ struct kevent *evbuf;
- size_t fds_size;
- struct fdrecord *fds;
+ size_t fds_size;
+ struct fdrecord *fds;
};
struct fdrecord {
- struct io *errio;
- enum io_condition mode;
+ struct io *errio;
+ enum io_condition mode;
};
void io_loop_handler_init(struct ioloop *ioloop)
{
- struct ioloop_handler_context *ctx;
+ struct ioloop_handler_context *ctx;
- ioloop->handler_context = ctx =
- p_new(ioloop->pool, struct ioloop_handler_context, 1);
+ ioloop->handler_context = ctx =
+ p_new(ioloop->pool, struct ioloop_handler_context, 1);
ctx->evbuf_size = INITIAL_BUF_SIZE;
- ctx->evbuf = p_new(ioloop->pool, struct kevent, ctx->evbuf_size);
- ctx->kq = kqueue();
- if (ctx->kq < 0)
- i_fatal("kqueue(): %m");
+ ctx->evbuf = p_new(ioloop->pool, struct kevent, ctx->evbuf_size);
+ ctx->kq = kqueue();
+ if (ctx->kq < 0)
+ i_fatal("kqueue() in io_loop_handler_init() failed: %m");
+ fd_close_on_exec(ctx->kq, TRUE);
- ctx->fds_size = INITIAL_BUF_SIZE;
- ctx->fds = p_new(ioloop->pool, struct fdrecord, ctx->fds_size);
+ ctx->fds_size = INITIAL_BUF_SIZE;
+ ctx->fds = p_new(ioloop->pool, struct fdrecord, ctx->fds_size);
}
void io_loop_handler_deinit(struct ioloop *ioloop)
{
if (close(ioloop->handler_context->kq) < 0)
- i_error("close(kqueue) failed: %m");
- p_free(ioloop->pool, ioloop->handler_context->evbuf);
- p_free(ioloop->pool, ioloop->handler_context->fds);
- p_free(ioloop->pool, ioloop->handler_context);
+ i_error("close(kqueue) in io_loop_handler_deinit() failed: %m");
+ p_free(ioloop->pool, ioloop->handler_context->evbuf);
+ p_free(ioloop->pool, ioloop->handler_context->fds);
+ p_free(ioloop->pool, ioloop->handler_context);
}
void io_loop_handle_add(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_ADD | EV_EOF, 0, 0, NULL };
- enum io_condition condition = io->condition & MASK;
+ struct ioloop_handler_context *ctx = ioloop->handler_context;
+ const int fd = io->fd;
+ struct kevent ev = { fd, 0, EV_ADD | EV_EOF, 0, 0, NULL };
+ enum io_condition condition = io->condition & MASK;
+
+ i_assert(io->callback != NULL);
- /* grow ctx->fds array if necessary */
- if ((size_t)fd >= ctx->fds_size) {
- size_t old_size = ctx->fds_size;
+ /* grow ctx->fds array if necessary */
+ if ((size_t)fd >= ctx->fds_size) {
+ size_t old_size = ctx->fds_size;
- ctx->fds_size = nearest_power((unsigned int)fd+1);
- i_assert(ctx->fds_size < (size_t)-1 / sizeof(int));
+ ctx->fds_size = nearest_power((unsigned int)fd+1);
+ i_assert(ctx->fds_size < (size_t)-1 / sizeof(int));
- ctx->fds = p_realloc(ioloop->pool, ctx->fds,
- sizeof(struct fdrecord) * old_size,
- sizeof(struct fdrecord) * ctx->fds_size);
- memset(ctx->fds + old_size, 0,
- sizeof(struct fdrecord) * (ctx->fds_size - old_size));
- }
+ ctx->fds = p_realloc(ioloop->pool, ctx->fds,
+ sizeof(struct fdrecord) * old_size,
+ sizeof(struct fdrecord) * ctx->fds_size);
+ memset(ctx->fds + old_size, 0,
+ sizeof(struct fdrecord) * (ctx->fds_size - old_size));
+ }
- if (condition & (IO_READ | IO_WRITE))
- ev.udata = io;
- if (condition & IO_ERROR)
- ctx->fds[fd].errio = io;
+ if (condition & (IO_READ | IO_WRITE))
+ ev.udata = io;
+ if (condition & IO_ERROR)
+ ctx->fds[fd].errio = io;
- if (condition & (IO_READ | IO_ERROR)) {
- ctx->fds[fd].mode |= condition;
- ev.filter = EVFILT_READ;
- kevent(ctx->kq, &ev, 1, NULL, 0, NULL);
- }
- if (condition & (IO_WRITE | IO_ERROR)) {
- ctx->fds[fd].mode |= condition;
- ev.filter = EVFILT_WRITE;
- kevent(ctx->kq, &ev, 1, NULL, 0, NULL);
- }
+ if (condition & (IO_READ | IO_ERROR)) {
+ ctx->fds[fd].mode |= condition;
+ ev.filter = EVFILT_READ;
+ if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
+ i_error("kevent(%d) in io_loop_handle_add() failed: %m",
+ fd);
+ }
+ }
+ if (condition & (IO_WRITE | IO_ERROR)) {
+ ctx->fds[fd].mode |= condition;
+ ev.filter = EVFILT_WRITE;
+ if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
+ i_error("kevent(%d) in io_loop_handle_add() failed: %m",
+ fd);
+ }
+ }
}
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 enum io_condition condition = io->condition & MASK;
+ 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 enum io_condition condition = io->condition & MASK;
- i_assert((size_t)fd < ctx->fds_size);
- i_assert(fds[fd].mode != 0);
+ i_assert((size_t)fd < ctx->fds_size);
- if (condition & IO_ERROR)
- fds[fd].errio = NULL;
- if (condition & (IO_READ | IO_ERROR)) {
- ev.filter = EVFILT_READ;
- fds[fd].mode &= ~condition;
- if ((fds[fd].mode & (IO_READ | IO_ERROR)) == 0)
- kevent(ctx->kq, &ev, 1, NULL, 0, NULL);
- }
- if (condition & (IO_WRITE | IO_ERROR)) {
- ev.filter = EVFILT_WRITE;
- fds[fd].mode &= ~condition;
- if ((fds[fd].mode & (IO_WRITE | IO_ERROR)) == 0)
- kevent(ctx->kq, &ev, 1, NULL, 0, NULL);
- }
+ if (condition & IO_ERROR)
+ fds[fd].errio = NULL;
+ if (condition & (IO_READ | IO_ERROR)) {
+ ev.filter = EVFILT_READ;
+ fds[fd].mode &= ~condition;
+ if ((fds[fd].mode & (IO_READ | IO_ERROR)) == 0) {
+ if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
+ i_error("kevent(%d) in io_loop_handle_remove "
+ "failed: %m", fd);
+ }
+ }
+ }
+ if (condition & (IO_WRITE | IO_ERROR)) {
+ ev.filter = EVFILT_WRITE;
+ fds[fd].mode &= ~condition;
+ if ((fds[fd].mode & (IO_WRITE | IO_ERROR)) == 0) {
+ if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
+ i_error("kevent(%d) in io_loop_handle_remove "
+ "failed: %m", fd);
+ }
+ }
+ }
}
void io_loop_handler_run(struct ioloop *ioloop)
{
- struct ioloop_handler_context *ctx = ioloop->handler_context;
- struct timeval tv;
- struct timespec ts;
- unsigned int t_id;
- int msecs, ret, i;
+ struct ioloop_handler_context *ctx = ioloop->handler_context;
+ struct timeval tv;
+ struct timespec ts;
+ unsigned int t_id;
+ int msecs, ret, i;
- /* get the time left for next timeout task */
- msecs = io_loop_get_wait_time(ioloop->timeouts, &tv, NULL);
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
+ /* get the time left for next timeout task */
+ msecs = io_loop_get_wait_time(ioloop->timeouts, &tv, NULL);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
- /* wait for events */
- ret = kevent (ctx->kq, NULL, 0, ctx->evbuf, ctx->evbuf_size, &ts);
- if (ret < 0 && errno != EINTR)
- i_fatal("kevent(): %m");
+ /* wait for events */
+ ret = kevent (ctx->kq, NULL, 0, ctx->evbuf, ctx->evbuf_size, &ts);
+ if (ret < 0 && errno != EINTR)
+ i_fatal("kevent(): %m");
- /* execute timeout handlers */
- io_loop_handle_timeouts(ioloop);
+ /* execute timeout handlers */
+ io_loop_handle_timeouts(ioloop);
- if (ret <= 0 || !ioloop->running) {
- /* no I/O events */
- return;
- }
+ if (ret <= 0 || !ioloop->running) {
+ /* no I/O events */
+ return;
+ }
- i_assert((size_t)ret <= ctx->evbuf_size);
+ i_assert((size_t)ret <= ctx->evbuf_size);
- /* loop through all received events */
- for (i = 0; i < ret; ++i) {
- struct io *io = ctx->evbuf[i].udata;
+ /* loop through all received events */
+ for (i = 0; i < ret; ++i) {
+ struct io *io = ctx->evbuf[i].udata;
- i_assert(ctx->evbuf[i].ident < ctx->fds_size);
+ i_assert(ctx->evbuf[i].ident < ctx->fds_size);
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;
+ struct io *errio = ctx->fds[ctx->evbuf[i].ident].errio;
- t_id = t_push();
- errio->callback(errio->context);
+ t_id = t_push();
+ errio->callback(errio->context);
if (t_pop() != t_id) {
- i_panic("Leaked a t_pop() call"
- " in I/O handler %p",
+ i_panic("Leaked a t_pop() call"
+ " in I/O handler %p",
(void *)errio->callback);
}
- } else if (ctx->fds[ctx->evbuf[i].ident].mode
- & (IO_WRITE | IO_READ)) {
- t_id = t_push();
- io->callback(io->context);
+ } 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) {
- i_panic("Leaked a t_pop() call"
- " in I/O handler %p",
+ i_panic("Leaked a t_pop() call"
+ " in I/O handler %p",
(void *)io->callback);
}
- } else
- i_panic("Unrecognized event");
- }
+ } else
+ i_panic("Unrecognized event");
+ }
}
#endif
Index: ioloop-notify-kqueue.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-notify-kqueue.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ioloop-notify-kqueue.c 30 Dec 2005 20:56:40 -0000 1.1
+++ ioloop-notify-kqueue.c 29 Jan 2006 10:32:37 -0000 1.2
@@ -15,11 +15,13 @@
#ifdef IOLOOP_NOTIFY_KQUEUE
#include "ioloop-internal.h"
+#include "fd-close-on-exec.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
+#include <sys/stat.h>
struct ioloop_notify_handler_context {
int kq;
@@ -53,7 +55,8 @@
ctx->event_io = NULL;
ctx->kq = kqueue();
if (ctx->kq < 0)
- i_fatal("kqueue() failed: %m");
+ i_fatal("kqueue() in io_loop_notify_handler_init() failed: %m");
+ fd_close_on_exec(ctx->kq, TRUE);
}
void io_loop_notify_handler_deinit(struct ioloop *ioloop)
@@ -61,8 +64,8 @@
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
- if (ctx->event_io)
- io_remove(ctx->event_io);
+ if (ctx->event_io)
+ io_remove(&ctx->event_io);
if (close(ctx->kq) < 0)
i_error("close(kqueue notify) failed: %m");
p_free(ioloop->pool, ctx);
@@ -75,6 +78,10 @@
for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) {
if (*io_p == io) {
*io_p = io->next;
+ if (io->next != NULL)
+ io->next->prev = io->prev;
+ io->prev = NULL;
+ io->next = NULL;
break;
}
}
@@ -90,25 +97,42 @@
| NOTE_REVOKE, 0, NULL };
struct io *io;
int fd;
+ struct stat sb;
+
+ i_assert(callback != NULL);
fd = open(path, O_RDONLY);
if (fd == -1) {
- i_error("open(%s) for notify failed: %m", path);
+ i_error("open(%s) for kq notify failed: %m", path);
return NULL;
}
- ev.ident = fd;
- ev.udata = io;
- if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
- i_error("kevent(%s) for notify failed: %m", path);
+ if (fstat(fd, &sb) < 0) {
+ i_error("fstat(%d, %s) for kq notify failed: %m", fd, path);
+ (void)close(fd);
+ return NULL;
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ (void)close(fd);
return NULL;
}
+ fd_close_on_exec(fd, TRUE);
io = p_new(ioloop->pool, struct io, 1);
io->fd = fd;
io->callback = callback;
io->context = context;
+ ev.ident = fd;
+ ev.udata = io;
+ if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
+ i_error("kevent(%d, %s) for notify failed: %m", fd, path);
+ p_free(ioloop->pool, io);
+ return NULL;
+ }
io->next = ioloop->notifys;
+ io->prev = NULL;
+ if (ioloop->notifys != NULL)
+ ioloop->notifys->prev = io;
ioloop->notifys = io;
if (ctx->event_io == NULL) {
@@ -116,7 +140,6 @@
io_add(ctx->kq, IO_READ, event_callback,
ioloop->notify_handler_context);
}
-
return io;
}
@@ -124,15 +147,16 @@
{
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
- struct kevent ev = { io->fd, 0, EV_DELETE, 0, 0, NULL };
- int ret;
+ struct kevent ev = { io->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL };
+ i_assert((io->condition & IO_NOTIFY) != 0);
+
+ if (kevent(ctx->kq, &ev, 1, NULL, 0, 0) < 0)
+ i_error("kevent(%d) for notify remove failed: %m", io->fd);
+ if (close(io->fd) < 0)
+ i_error("close(%d) failed: %m", io->fd);
unchain_io(ioloop, io);
p_free(ioloop->pool, io);
-
- ret = kevent(ctx->kq, &ev, 1, NULL, 0, 0);
- if (ret == -1)
- i_error("kevent() for notify failed: %m");
}
#endif
Index: ioloop.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- ioloop.c 14 Jan 2006 18:47:22 -0000 1.31
+++ ioloop.c 29 Jan 2006 10:32:37 -0000 1.32
@@ -279,6 +279,8 @@
*_ioloop = NULL;
+ io_loop_notify_handler_deinit(ioloop);
+
while (ioloop->ios != NULL) {
struct io *io = ioloop->ios;
@@ -295,8 +297,7 @@
}
timeout_destroy(ioloop, &ioloop->timeouts);
}
-
- io_loop_notify_handler_deinit(ioloop);
+
io_loop_handler_deinit(ioloop);
/* ->prev won't work unless loops are destroyed in create order */
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index/dbox dbox-save.c, 1.3,
1.4 dbox-transaction.c, 1.1, 1.2 dbox-uidlist.c, 1.14,
1.15 dbox-uidlist.h, 1.3, 1.4
- Next message: [dovecot-cvs] dovecot/src/lib ioloop-internal.h, 1.15,
1.16 ioloop-notify-dn.c, 1.13, 1.14 ioloop-notify-inotify.c,
1.8, 1.9 ioloop-notify-kqueue.c, 1.2, 1.3 ioloop.c, 1.32, 1.33
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list