dovecot: Changed io_add_notify() API so that it can return "file...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jul 9 07:04:58 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/772f4e8bd2a9
changeset: 5937:772f4e8bd2a9
user: Timo Sirainen <tss at iki.fi>
date: Mon Jul 09 06:59:57 2007 +0300
description:
Changed io_add_notify() API so that it can return "file doesn't exist"
error.
diffstat:
5 files changed, 74 insertions(+), 39 deletions(-)
src/lib-storage/index/index-mailbox-check.c | 2 -
src/lib/ioloop-notify-dn.c | 38 +++++++++++++------------
src/lib/ioloop-notify-inotify.c | 41 +++++++++++++++++++--------
src/lib/ioloop-notify-kqueue.c | 11 +++----
src/lib/ioloop.h | 21 +++++++++++--
diffs (284 lines):
diff -r 2133c966701a -r 772f4e8bd2a9 src/lib-storage/index/index-mailbox-check.c
--- a/src/lib-storage/index/index-mailbox-check.c Mon Jul 09 06:47:17 2007 +0300
+++ b/src/lib-storage/index/index-mailbox-check.c Mon Jul 09 06:59:57 2007 +0300
@@ -73,7 +73,7 @@ void index_mailbox_check_add(struct inde
struct io *io = NULL;
struct index_notify_io *aio;
- io = io_add_notify(path, notify_callback, ibox);
+ (void)io_add_notify(path, notify_callback, ibox, &io);
if (io != NULL) {
aio = i_new(struct index_notify_io, 1);
aio->io = io;
diff -r 2133c966701a -r 772f4e8bd2a9 src/lib/ioloop-notify-dn.c
--- a/src/lib/ioloop-notify-dn.c Mon Jul 09 06:47:17 2007 +0300
+++ b/src/lib/ioloop-notify-dn.c Mon Jul 09 06:59:57 2007 +0300
@@ -72,48 +72,51 @@ static void dnotify_input(struct ioloop
}
#undef io_add_notify
-struct io *io_add_notify(const char *path, io_callback_t *callback,
- void *context)
+enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
+ void *context, struct io **io_r)
{
struct ioloop_notify_handler_context *ctx =
current_ioloop->notify_handler_context;
- int fd;
+ int fd, ret;
+
+ *io_r = NULL;
if (ctx == NULL)
ctx = io_loop_notify_handler_init();
if (ctx->disabled)
- return NULL;
+ return IO_NOTIFY_DISABLED;
fd = open(path, O_RDONLY);
if (fd == -1) {
- i_error("open(%s) for dnotify failed: %m", path);
- return NULL;
+ if (errno != ENOENT)
+ i_error("open(%s) for dnotify failed: %m", path);
+ return IO_NOTIFY_NOTFOUND;
}
if (fcntl(fd, F_SETSIG, SIGRTMIN) < 0) {
- if (errno == EINVAL) {
- /* not supported, disable dnotify */
- ctx->disabled = TRUE;
- } else {
+ /* EINVAL means there's no realtime signals and no dnotify */
+ if (errno != EINVAL)
i_error("fcntl(F_SETSIG) failed: %m");
- }
+ ctx->disabled = TRUE;
(void)close(fd);
- return NULL;
+ return IO_NOTIFY_DISABLED;
}
if (fcntl(fd, F_NOTIFY, DN_CREATE | DN_DELETE | DN_RENAME |
DN_MULTISHOT) < 0) {
if (errno == ENOTDIR) {
/* we're trying to add dnotify to a non-directory fd.
fail silently. */
- } else if (errno == EINVAL) {
+ ret = IO_NOTIFY_NOTFOUND;
+ } else {
/* dnotify not in kernel. disable it. */
+ if (errno != EINVAL)
+ i_error("fcntl(F_NOTIFY) failed: %m");
ctx->disabled = TRUE;
- } else {
- i_error("fcntl(F_NOTIFY) failed: %m");
+ ret = IO_NOTIFY_DISABLED;
}
(void)fcntl(fd, F_SETSIG, 0);
(void)close(fd);
- return NULL;
+ return ret;
}
if (ctx->event_io == NULL) {
@@ -121,7 +124,8 @@ struct io *io_add_notify(const char *pat
dnotify_input, current_ioloop);
}
- return io_notify_fd_add(&ctx->fd_ctx, fd, callback, context);
+ *io_r = io_notify_fd_add(&ctx->fd_ctx, fd, callback, context);
+ return IO_NOTIFY_ADDED;
}
void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
diff -r 2133c966701a -r 772f4e8bd2a9 src/lib/ioloop-notify-inotify.c
--- a/src/lib/ioloop-notify-inotify.c Mon Jul 09 06:47:17 2007 +0300
+++ b/src/lib/ioloop-notify-inotify.c Mon Jul 09 06:59:57 2007 +0300
@@ -6,6 +6,7 @@
#ifdef IOLOOP_NOTIFY_INOTIFY
#include "fd-close-on-exec.h"
+#include "fd-set-nonblock.h"
#include "ioloop-internal.h"
#include "ioloop-notify-fd.h"
#include "buffer.h"
@@ -62,12 +63,18 @@ static bool inotify_input_more(struct io
pos += sizeof(*event) + event->len;
io = io_notify_fd_find(&ctx->fd_ctx, event->wd);
- if (io != NULL)
+ if (io != NULL) {
+ if ((event->mask & IN_IGNORED) != 0) {
+ /* calling inotify_rm_watch() would now give
+ EINVAL */
+ io->fd = -1;
+ }
io->io.callback(io->io.context);
+ }
}
if (pos != ret)
i_error("read(inotify) returned partial event");
- return TRUE;
+ return (size_t)ret >= sizeof(event_buf)-512;
}
static void inotify_input(struct ioloop *ioloop)
@@ -76,28 +83,33 @@ static void inotify_input(struct ioloop
}
#undef io_add_notify
-struct io *io_add_notify(const char *path, io_callback_t *callback,
- void *context)
+enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
+ void *context, struct io **io_r)
{
struct ioloop_notify_handler_context *ctx =
current_ioloop->notify_handler_context;
- int fd;
+ int wd;
+
+ *io_r = NULL;
if (ctx == NULL)
ctx = io_loop_notify_handler_init();
if (ctx->disabled)
- return NULL;
+ return IO_NOTIFY_DISABLED;
- fd = inotify_add_watch(ctx->inotify_fd, path,
+ wd = inotify_add_watch(ctx->inotify_fd, path,
IN_CREATE | IN_DELETE | IN_MOVE |
IN_CLOSE | IN_MODIFY);
- if (fd < 0) {
+ if (wd < 0) {
+ if (errno == ENOENT)
+ return IO_NOTIFY_NOTFOUND;
+
/* ESTALE could happen with NFS. Don't bother giving an error
message then. */
if (errno != ESTALE)
i_error("inotify_add_watch(%s) failed: %m", path);
ctx->disabled = TRUE;
- return NULL;
+ return IO_NOTIFY_DISABLED;
}
if (ctx->event_io == NULL) {
@@ -105,7 +117,8 @@ struct io *io_add_notify(const char *pat
inotify_input, current_ioloop);
}
- return io_notify_fd_add(&ctx->fd_ctx, fd, callback, context);
+ *io_r = io_notify_fd_add(&ctx->fd_ctx, wd, callback, context);
+ return IO_NOTIFY_ADDED;
}
void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
@@ -114,8 +127,10 @@ void io_loop_notify_remove(struct ioloop
ioloop->notify_handler_context;
struct io_notify *io = (struct io_notify *)_io;
- if (inotify_rm_watch(ctx->inotify_fd, io->fd) < 0)
- i_error("inotify_rm_watch() failed: %m");
+ if (io->fd != -1) {
+ if (inotify_rm_watch(ctx->inotify_fd, io->fd) < 0)
+ i_error("inotify_rm_watch() failed: %m");
+ }
io_notify_fd_free(&ctx->fd_ctx, io);
@@ -142,6 +157,7 @@ static struct ioloop_notify_handler_cont
ctx->disabled = TRUE;
} else {
fd_close_on_exec(ctx->inotify_fd, TRUE);
+ fd_set_nonblock(ctx->inotify_fd, TRUE);
}
return ctx;
}
@@ -154,6 +170,7 @@ void io_loop_notify_handler_deinit(struc
if (ctx->inotify_fd != -1) {
if (close(ctx->inotify_fd) < 0)
i_error("close(inotify) failed: %m");
+ ctx->inotify_fd = -1;
}
i_free(ctx);
}
diff -r 2133c966701a -r 772f4e8bd2a9 src/lib/ioloop-notify-kqueue.c
--- a/src/lib/ioloop-notify-kqueue.c Mon Jul 09 06:47:17 2007 +0300
+++ b/src/lib/ioloop-notify-kqueue.c Mon Jul 09 06:59:57 2007 +0300
@@ -105,8 +105,8 @@ void io_loop_notify_handler_deinit(struc
}
#undef io_add_notify
-struct io *io_add_notify(const char *path, io_callback_t *callback,
- void *context)
+enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
+ void *context, struct io **io_r)
{
struct ioloop_notify_handler_context *ctx =
current_ioloop->notify_handler_context;
@@ -121,7 +121,7 @@ struct io *io_add_notify(const char *pat
if (fd == -1) {
if (errno != ENOENT)
i_error("open(%s) for kq notify failed: %m", path);
- return NULL;
+ return IO_NOTIFY_NOTFOUND;
}
fd_close_on_exec(fd, TRUE);
@@ -140,14 +140,15 @@ struct io *io_add_notify(const char *pat
i_error("kevent(%d, %s) for notify failed: %m", fd, path);
(void)close(fd);
i_free(io);
- return NULL;
+ return IO_NOTIFY_DISABLED;
}
if (ctx->event_io == NULL) {
ctx->event_io = io_add(ctx->kq, IO_READ, event_callback,
current_ioloop->notify_handler_context);
}
- return &io->io;
+ *io_r = &io->io;
+ return IO_NOTIFY_ADDED;
}
void io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
diff -r 2133c966701a -r 772f4e8bd2a9 src/lib/ioloop.h
--- a/src/lib/ioloop.h Mon Jul 09 06:47:17 2007 +0300
+++ b/src/lib/ioloop.h Mon Jul 09 06:59:57 2007 +0300
@@ -17,6 +17,12 @@ enum io_condition {
/* internal */
IO_NOTIFY = 0x08
+};
+
+enum io_notify_result {
+ IO_NOTIFY_ADDED,
+ IO_NOTIFY_NOTFOUND,
+ IO_NOTIFY_DISABLED
};
typedef void io_callback_t(void *context);
@@ -40,10 +46,17 @@ struct io *io_add(int fd, enum io_condit
#define io_add(fd, condition, callback, context) \
CONTEXT_CALLBACK(io_add, io_callback_t, \
callback, context, fd, condition)
-struct io *io_add_notify(const char *path, io_callback_t *callback,
- void *context);
-#define io_add_notify(path, callback, context) \
- CONTEXT_CALLBACK(io_add_notify, io_callback_t, callback, context, path)
+enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
+ void *context, struct io **io_r);
+#ifdef CONTEXT_TYPE_SAFETY
+# define io_add_notify(path, callback, context, io_r) \
+ ({(void)(1 ? 0 : callback(context)); \
+ io_add_notify(path, (io_callback_t *)callback, context, io_r); })
+#else
+# define io_add_notify(path, callback, context, io_r) \
+ io_add_notify(path, (io_callback_t *)callback, context, io_r)
+#endif
+
/* Remove I/O handler, and set io pointer to NULL. */
void io_remove(struct io **io);
More information about the dovecot-cvs
mailing list