Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3781:d996a407aa4b HEAD
Fix IO_ERROR behaviour. Patch by Vaclav Haisman
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 30 Dec 2005 22:56:05 +0200 |
parents | 0128534525d8 |
children | c67f77647a6e |
files | src/lib/ioloop-kqueue.c |
diffstat | 1 files changed, 16 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/ioloop-kqueue.c Fri Dec 30 22:40:19 2005 +0200 +++ b/src/lib/ioloop-kqueue.c Fri Dec 30 22:56:05 2005 +0200 @@ -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,8 @@ 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); @@ -66,8 +71,8 @@ { 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 +108,10 @@ 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 +165,8 @@ 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(); @@ -170,9 +176,8 @@ " in I/O handler %p", (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) { @@ -180,7 +185,8 @@ " in I/O handler %p", (void *)io->callback); } - } + } else + i_panic("Unrecognized event"); } }