Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7459:63cd8ec2007a HEAD
Better error handling for dnotify failures.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 24 Apr 2008 17:24:32 +0300 |
parents | 43674a726a92 |
children | e1fe3d080314 |
files | src/lib/ioloop-notify-dn.c |
diffstat | 1 files changed, 29 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/ioloop-notify-dn.c Thu Apr 24 17:03:10 2008 +0300 +++ b/src/lib/ioloop-notify-dn.c Thu Apr 24 17:24:32 2008 +0300 @@ -29,6 +29,21 @@ static struct ioloop_notify_handler_context *io_loop_notify_handler_init(void); +static void ioloop_dnotify_disable(struct ioloop_notify_handler_context *ctx) +{ + if (ctx->disabled) + return; + + if (--sigrt_refcount == 0) + signal(SIGRTMIN, SIG_IGN); + + if (close(ctx->event_pipe[0]) < 0) + i_error("close(dnotify pipe[0]) failed: %m"); + if (close(ctx->event_pipe[1]) < 0) + i_error("close(dnotify pipe[1]) failed: %m"); + ctx->disabled = TRUE; +} + static void sigrt_handler(int signo ATTR_UNUSED, siginfo_t *si, void *data ATTR_UNUSED) { @@ -37,9 +52,14 @@ int saved_errno = errno; int ret; + if (ctx->disabled) + return; + ret = write(ctx->event_pipe[1], &si->si_fd, sizeof(int)); - if (ret < 0 && errno != EINTR && errno != EAGAIN) - i_fatal("write(event_pipe) failed: %m"); + if (ret < 0 && errno != EINTR && errno != EAGAIN) { + i_error("write(dnotify pipe) failed: %m"); + ioloop_dnotify_disable(ctx); + } i_assert(ret <= 0 || ret == sizeof(int)); @@ -55,9 +75,9 @@ ret = read(ctx->event_pipe[0], fd_buf, sizeof(fd_buf)); if (ret < 0) - i_fatal("read(event_pipe) failed: %m"); + i_fatal("read(dnotify pipe) failed: %m"); if ((ret % sizeof(fd_buf[0])) != 0) - i_fatal("read(event_pipe) returned %d", ret); + i_fatal("read(dnotify pipe) returned %d", ret); ret /= sizeof(fd_buf[0]); if (gettimeofday(&ioloop_timeval, &ioloop_timezone) < 0) @@ -77,7 +97,7 @@ { struct ioloop_notify_handler_context *ctx = current_ioloop->notify_handler_context; - int fd, ret; + int fd; *io_r = NULL; @@ -99,7 +119,7 @@ /* EINVAL means there's no realtime signals and no dnotify */ if (errno != EINVAL) i_error("fcntl(F_SETSIG) failed: %m"); - ctx->disabled = TRUE; + ioloop_dnotify_disable(ctx); (void)close(fd); return IO_NOTIFY_NOSUPPORT; } @@ -112,7 +132,7 @@ /* dnotify not in kernel. disable it. */ if (errno != EINVAL) i_error("fcntl(F_NOTIFY) failed: %m"); - ctx->disabled = TRUE; + ioloop_dnotify_disable(ctx); } (void)fcntl(fd, F_SETSIG, 0); (void)close(fd); @@ -179,7 +199,7 @@ if (errno == EINVAL) { /* kernel is too old to understand even RT signals, so there's no way dnotify works */ - ctx->disabled = TRUE; + ioloop_dnotify_disable(ctx); } else { i_fatal("sigaction(SIGRTMIN) failed: %m"); } @@ -193,14 +213,7 @@ struct ioloop_notify_handler_context *ctx = ioloop->notify_handler_context; - if (--sigrt_refcount == 0) - signal(SIGRTMIN, SIG_IGN); - - if (close(ctx->event_pipe[0]) < 0) - i_error("close(event_pipe[0]) failed: %m"); - if (close(ctx->event_pipe[1]) < 0) - i_error("close(event_pipe[1]) failed: %m"); - + ioloop_dnotify_disable(ctx); i_free(ctx); }