]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
master: Fixed logging process related bugs.
authorTimo Sirainen <tss@iki.fi>
Thu, 30 Apr 2009 21:56:47 +0000 (17:56 -0400)
committerTimo Sirainen <tss@iki.fi>
Thu, 30 Apr 2009 21:56:47 +0000 (17:56 -0400)
--HG--
branch : HEAD

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

index 6d0abe2b675bc859f62dccbad03db18641d67dbb..7566a52b63f7d491e8851abda46b5324dde0b087 100644 (file)
@@ -1,9 +1,12 @@
 /* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
 
 #include "common.h"
-#include "fd-close-on-exec.h"
 #include "array.h"
+#include "hash.h"
+#include "ioloop.h"
+#include "fd-close-on-exec.h"
 #include "service.h"
+#include "service-process.h"
 #include "service-log.h"
 
 #include <unistd.h>
@@ -62,6 +65,21 @@ int services_log_init(struct service_list *service_list)
        return 0;
 }
 
+static void service_remove_log_io_writes(struct service *service)
+{
+       struct hash_iterate_context *iter;
+       void *key, *value;
+
+       iter = hash_table_iterate_init(service->list->pids);
+       while (hash_table_iterate(iter, &key, &value)) {
+               struct service_process *process = value;
+
+               if (process->io_log_write != NULL)
+                       io_remove(&process->io_log_write);
+       }
+       hash_table_iterate_deinit(&iter);
+}
+
 void services_log_deinit(struct service_list *service_list)
 {
        struct service *const *services;
@@ -80,6 +98,7 @@ void services_log_deinit(struct service_list *service_list)
                        }
                        services[i]->log_fd[0] = -1;
                        services[i]->log_fd[1] = -1;
+                       service_remove_log_io_writes(services[i]);
                }
        }
 }
index 92a96a6cd945460a120f4b2264ea84ea6b21af85..aa13f3c304b672efb3a494aa15d41f51385931c6 100644 (file)
@@ -372,10 +372,37 @@ service_process_create(struct service *service, const char *const *auth_args,
        return process;
 }
 
+static void service_process_log_bye(struct service_process *process)
+{
+       const char *data;
+
+       if (process->service->log_fd[1] == -1) {
+               /* stopping all services */
+               return;
+       }
+
+       data = t_strdup_printf("\001%c%s bye\n",
+                              LOG_TYPE_OPTION+1, dec2str(process->pid));
+       if (write(process->service->log_fd[1], data, strlen(data)) < 0) {
+               if (errno != EAGAIN)
+                       i_error("write(log process) failed: %m");
+               else {
+                       process->io_log_write =
+                               io_add(process->service->log_fd[1], IO_WRITE,
+                                      service_process_log_bye, process);
+                       service_process_ref(process);
+               }
+       } else {
+               if (process->io_log_write != NULL) {
+                       io_remove(&process->io_log_write);
+                       service_process_unref(process);
+               }
+       }
+}
+
 void service_process_destroy(struct service_process *process)
 {
        struct service *service = process->service;
-       const char *data;
 
        hash_table_remove(service->list->pids, &process->pid);
 
@@ -398,16 +425,7 @@ void service_process_destroy(struct service_process *process)
                break;
        }
 
-       data = t_strdup_printf("\001%c%s bye\n",
-                              LOG_TYPE_OPTION+1, dec2str(process->pid));
-       if (write(process->service->log_fd[1], data, strlen(data)) < 0) {
-               if (errno != EAGAIN)
-                       i_error("write(log process) failed: %m");
-               else {
-                       //FIXME:process->io_log_write = io_add();
-                       //return;
-               }
-       }
+       service_process_log_bye(process);
 
        process->destroyed = TRUE;
        service_process_unref(process);
@@ -427,6 +445,7 @@ int service_process_unref(struct service_process *process)
        if (--process->refcount > 0)
                return TRUE;
 
+       i_assert(process->io_log_write == NULL);
        i_assert(process->destroyed);
 
        i_free(process);
@@ -543,7 +562,7 @@ static void service_process_log(struct service_process *process,
           this process's logging */
        data = t_strdup_printf("\001%c%s %s %s\n",
                               type+1, my_pid, dec2str(process->pid), str);
-       if (write_full(process->service->log_fd[1], data, strlen(data)) < 0) {
+       if (write(process->service->log_fd[1], data, strlen(data)) < 0) {
                i_error("write(log process) failed: %m");
                i_log_type(type, "%s", str);
        }
index aca151efcee36c5d0802cf58954c8b2479b71b86..61b011ea7ca72bafabc486d8ea4e881657f8bbd9 100644 (file)
@@ -19,6 +19,8 @@ struct service_process {
 
        /* kill the process if it doesn't send initial status notification */
        struct timeout *to_status;
+       /* we're waiting to be able to send "bye" to log process */
+       struct io *io_log_write;
 
        unsigned int destroyed:1;
 };