Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3959:ef5595d6ddec HEAD
Cleanups: Make io_remove() do the linked list updating also for notify
handlers. Removed notify_context from struct io, and moved it to a new
struct inotify_io.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 29 Jan 2006 12:55:22 +0200 |
parents | 3e9b43d0cd80 |
children | aeb424e64f24 |
files | src/lib/ioloop-internal.h src/lib/ioloop-notify-dn.c src/lib/ioloop-notify-inotify.c src/lib/ioloop-notify-kqueue.c src/lib/ioloop.c |
diffstat | 5 files changed, 45 insertions(+), 88 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/ioloop-internal.h Sun Jan 29 12:32:37 2006 +0200 +++ b/src/lib/ioloop-internal.h Sun Jan 29 12:55:22 2006 +0200 @@ -20,6 +20,7 @@ }; struct io { + /* use a doubly linked list so that io_remove() is quick */ struct io *prev, *next; int fd; @@ -27,8 +28,6 @@ io_callback_t *callback; void *context; - - int notify_context; }; struct timeout {
--- a/src/lib/ioloop-notify-dn.c Sun Jan 29 12:32:37 2006 +0200 +++ b/src/lib/ioloop-notify-dn.c Sun Jan 29 12:55:22 2006 +0200 @@ -112,9 +112,6 @@ io->callback = callback; io->context = context; - - io->next = ioloop->notifys; - ioloop->notifys = io; return io; } @@ -122,17 +119,6 @@ { struct ioloop_notify_handler_context *ctx = ioloop->notify_handler_context; - struct io **io_p; - - if (ctx->disabled) - return; - - for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) { - if (*io_p == io) { - *io_p = io->next; - break; - } - } if (fcntl(io->fd, F_NOTIFY, 0) < 0) i_error("fcntl(F_NOTIFY, 0) failed: %m"); @@ -141,8 +127,6 @@ if (close(io->fd)) i_error("close(dnotify) failed: %m"); - p_free(ioloop->pool, io); - if (ioloop->notifys == NULL) io_remove(&ctx->event_io); }
--- a/src/lib/ioloop-notify-inotify.c Sun Jan 29 12:32:37 2006 +0200 +++ b/src/lib/ioloop-notify-inotify.c Sun Jan 29 12:55:22 2006 +0200 @@ -19,6 +19,11 @@ #define INITIAL_INOTIFY_BUFLEN (FILENAME_MAX + sizeof(struct inotify_event)) #define MAXIMAL_INOTIFY_BUFLEN (32*1024) +struct inotify_io { + struct io io; + int wd; +}; + struct ioloop_notify_handler_context { int inotify_fd; @@ -62,7 +67,9 @@ while ((size_t)required_bytes > sizeof(*event)) { for (io = ioloop->notifys; io != NULL; io = io->next) { - if (io->notify_context == event->wd) { + struct inotify_io *iio = (struct inotify_io *)io; + + if (iio->wd == event->wd) { io->callback(io->context); break; } @@ -93,7 +100,7 @@ { struct ioloop_notify_handler_context *ctx = ioloop->notify_handler_context; - struct io *io; + struct inotify_io *io; int watchdescriptor; if (ctx->disabled) @@ -114,43 +121,26 @@ event_callback, ioloop); } - io = p_new(ioloop->pool, struct io, 1); - io->fd = -1; + io = p_new(ioloop->pool, struct inotify_io, 1); + io->io.fd = -1; - io->callback = callback; - io->context = context; - io->notify_context = watchdescriptor; - - io->next = ioloop->notifys; - ioloop->notifys = io; + io->io.callback = callback; + io->io.context = context; + io->wd = watchdescriptor; return io; } -void io_loop_notify_remove(struct ioloop *ioloop, struct io *io) +void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io) { struct ioloop_notify_handler_context *ctx = ioloop->notify_handler_context; - struct io **io_p; - - if (ctx->disabled) - return; + struct inotify_io *io = (struct inotify_io *)_io; - for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) { - if (*io_p == io) { - *io_p = io->next; - break; - } - } - - if (inotify_rm_watch(ctx->inotify_fd, io->notify_context) < 0) + if (inotify_rm_watch(ctx->inotify_fd, io->wd) < 0) i_error("inotify_rm_watch() failed: %m"); - p_free(ioloop->pool, io); - - if (ioloop->notifys == NULL) { + if (ioloop->notifys == NULL) io_remove(&ctx->event_io); - ctx->event_io = NULL; - } } void io_loop_notify_handler_init(struct ioloop *ioloop)
--- a/src/lib/ioloop-notify-kqueue.c Sun Jan 29 12:32:37 2006 +0200 +++ b/src/lib/ioloop-notify-kqueue.c Sun Jan 29 12:55:22 2006 +0200 @@ -38,10 +38,8 @@ i_fatal("gettimeofday() failed: %m"); ioloop_time = ioloop_timeval.tv_sec; - if (kevent(ctx->kq, NULL, 0, &ev, 1, 0) < 0) { + if (kevent(ctx->kq, NULL, 0, &ev, 1, 0) < 0) i_fatal("kevent() failed: %m"); - return; - } io = ev.udata; io->callback(io->context); } @@ -52,7 +50,6 @@ ctx = ioloop->notify_handler_context = p_new(ioloop->pool, struct ioloop_notify_handler_context, 1); - ctx->event_io = NULL; ctx->kq = kqueue(); if (ctx->kq < 0) i_fatal("kqueue() in io_loop_notify_handler_init() failed: %m"); @@ -71,22 +68,6 @@ p_free(ioloop->pool, ctx); } -static void unchain_io (struct ioloop *ioloop, struct io * io) -{ - struct io **io_p; - - 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; - } - } -} - struct io *io_loop_notify_add(struct ioloop *ioloop, const char *path, io_callback_t *callback, void *context) { @@ -129,11 +110,6 @@ 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) { ctx->event_io = @@ -155,8 +131,6 @@ 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); } #endif
--- a/src/lib/ioloop.c Sun Jan 29 12:32:37 2006 +0200 +++ b/src/lib/ioloop.c Sun Jan 29 12:55:22 2006 +0200 @@ -33,7 +33,6 @@ io_loop_handle_add(current_ioloop, io); - /* have to append it, or io_destroy() breaks */ io->next = current_ioloop->ios; current_ioloop->ios = io; @@ -53,6 +52,12 @@ io = io_loop_notify_add(current_ioloop, path, callback, context); if (io != NULL) io->condition |= IO_NOTIFY; + + io->next = current_ioloop->notifys; + current_ioloop->notifys = io; + + if (io->next != NULL) + io->next->prev = io; return io; } @@ -62,24 +67,29 @@ *_io = NULL; - if ((io->condition & IO_NOTIFY) != 0) { - io_loop_notify_remove(current_ioloop, io); - return; + /* unlink from linked list */ + if (io->prev != NULL) + io->prev->next = io->next; + else { + if ((io->condition & IO_NOTIFY) == 0) + current_ioloop->ios = io->next; + else + current_ioloop->notifys = io->next; } - - /* notify the real I/O handler */ - io_loop_handle_remove(current_ioloop, io); - - if (current_ioloop->next_io == io) - current_ioloop->next_io = io->next; - - if (io->prev == NULL) - current_ioloop->ios = io->next; - else - io->prev->next = io->next; if (io->next != NULL) io->next->prev = io->prev; + if ((io->condition & IO_NOTIFY) == 0) { + /* if we got here from an I/O handler callback, make sure we + don't try to handle this one next. */ + if (current_ioloop->next_io == io) + current_ioloop->next_io = io->next; + + io_loop_handle_remove(current_ioloop, io); + } else { + io_loop_notify_remove(current_ioloop, io); + } + p_free(current_ioloop->pool, io); }