]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
master: If anvil isn't used, read and discard all anvil input coming from mail processes.
authorTimo Sirainen <tss@iki.fi>
Wed, 30 Sep 2009 17:03:07 +0000 (13:03 -0400)
committerTimo Sirainen <tss@iki.fi>
Wed, 30 Sep 2009 17:03:07 +0000 (13:03 -0400)
--HG--
branch : HEAD

src/master/service-anvil.c
src/master/service-anvil.h
src/master/service-process.c
src/master/service.h

index 25c9cdf61fe98a7531ec04e90132c86c07f28e77..76b32a908f5d72be5d9c5cbd94ca5dd40201619d 100644 (file)
@@ -1,6 +1,7 @@
 /* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
 
 #include "common.h"
+#include "ioloop.h"
 #include "fd-close-on-exec.h"
 #include "fd-set-nonblock.h"
 #include "service.h"
 
 #define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n"
 
+static void
+anvil_input_fd_discard(struct service_list *service_list, int fd)
+{
+       char buf[1024];
+       ssize_t ret;
+
+       ret = read(fd, buf, sizeof(buf));
+       if (ret <= 0) {
+               i_error("read(anvil fd) failed: %m");
+               io_remove(&service_list->anvil_io_blocking);
+               io_remove(&service_list->anvil_io_nonblocking);
+       }
+}
+
+static void anvil_input_blocking_discard(struct service_list *service_list)
+{
+       anvil_input_fd_discard(service_list,
+                              service_list->blocking_anvil_fd[0]);
+}
+
+static void anvil_input_nonblocking_discard(struct service_list *service_list)
+{
+       anvil_input_fd_discard(service_list,
+                              service_list->nonblocking_anvil_fd[0]);
+}
+
+static void service_list_anvil_discard_input(struct service_list *service_list)
+{
+       service_list->anvil_io_blocking =
+               io_add(service_list->blocking_anvil_fd[0], IO_READ,
+                      anvil_input_blocking_discard, service_list);
+       service_list->anvil_io_nonblocking =
+               io_add(service_list->nonblocking_anvil_fd[0], IO_READ,
+                      anvil_input_nonblocking_discard, service_list);
+}
+
 static int anvil_send_handshake(int fd, const char **error_r)
 {
        ssize_t ret;
@@ -75,6 +112,7 @@ int service_list_init_anvil(struct service_list *service_list,
        service_list->anvil_kills =
                service_process_notify_init(service_list->nonblocking_anvil_fd[1],
                                            service_process_write_anvil_kill);
+       service_list_anvil_discard_input(service_list);
        return 0;
 }
 
@@ -90,3 +128,18 @@ void service_list_deinit_anvil(struct service_list *service_list)
        if (close(service_list->nonblocking_anvil_fd[1]) < 0)
                i_error("close(anvil) failed: %m");
 }
+
+void service_anvil_process_created(struct service *service)
+{
+       if (service->list->anvil_io_blocking != NULL) {
+               io_remove(&service->list->anvil_io_blocking);
+               io_remove(&service->list->anvil_io_nonblocking);
+       }
+}
+
+void service_anvil_process_destroyed(struct service *service)
+{
+       if (service->process_count == 0 &&
+           service->list->anvil_io_blocking == NULL)
+               service_list_anvil_discard_input(service->list);
+}
index 425a3be5ea47c46cdbc0d7c6208df159df2fad3d..05c6473eba4eb39558ba9e7b684a431f716da833 100644 (file)
@@ -5,4 +5,7 @@ int service_list_init_anvil(struct service_list *service_list,
                            const char **error_r);
 void service_list_deinit_anvil(struct service_list *service_list);
 
+void service_anvil_process_created(struct service *service);
+void service_anvil_process_destroyed(struct service *service);
+
 #endif
index f9979fa6c4ccce9a8982441ecc627d6d2c3a766c..5d4b69638031a83da963d40f418f033c365bff70 100644 (file)
@@ -20,6 +20,7 @@
 #include "master-service-settings.h"
 #include "dup2-array.h"
 #include "service.h"
+#include "service-anvil.h"
 #include "service-log.h"
 #include "service-auth-server.h"
 #include "service-auth-source.h"
@@ -555,6 +556,9 @@ service_process_create(struct service *service, const char *const *auth_args,
                service_process_auth_source_init(process, fd[0]);
                (void)close(fd[1]);
                break;
+       case SERVICE_TYPE_ANVIL:
+               service_anvil_process_created(service);
+               /* fall through */
        default:
                process = i_new(struct service_process, 1);
                process->service = service;
@@ -602,6 +606,9 @@ void service_process_destroy(struct service_process *process)
        case SERVICE_TYPE_AUTH_SOURCE:
                service_process_auth_source_deinit(process);
                break;
+       case SERVICE_TYPE_ANVIL:
+               service_anvil_process_destroyed(service);
+               break;
        default:
                break;
        }
index a755a5862d750bfd0d3b58ceb54e6b48a3bbc967..76751fb0f54eb68b3780f3ddc47ecac8a1ba1e66 100644 (file)
@@ -121,6 +121,7 @@ struct service_list {
        /* used by master process to notify about dying processes */
        int nonblocking_anvil_fd[2];
        struct service_process_notify *anvil_kills;
+       struct io *anvil_io_blocking, *anvil_io_nonblocking;
 
        ARRAY_DEFINE(services, struct service *);