changeset 9182:2f293c844e31 HEAD

master: Fixed logging process related bugs.
author Timo Sirainen <tss@iki.fi>
date Thu, 30 Apr 2009 17:56:47 -0400
parents 150a98d2407c
children bfe448b4951f
files src/master/service-log.c src/master/service-process.c src/master/service-process.h
diffstat 3 files changed, 53 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/master/service-log.c	Thu Apr 30 17:02:33 2009 -0400
+++ b/src/master/service-log.c	Thu Apr 30 17:56:47 2009 -0400
@@ -1,9 +1,12 @@
 /* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
 
 #include "common.h"
+#include "array.h"
+#include "hash.h"
+#include "ioloop.h"
 #include "fd-close-on-exec.h"
-#include "array.h"
 #include "service.h"
+#include "service-process.h"
 #include "service-log.h"
 
 #include <unistd.h>
@@ -62,6 +65,21 @@
 	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 @@
 			}
 			services[i]->log_fd[0] = -1;
 			services[i]->log_fd[1] = -1;
+			service_remove_log_io_writes(services[i]);
 		}
 	}
 }
--- a/src/master/service-process.c	Thu Apr 30 17:02:33 2009 -0400
+++ b/src/master/service-process.c	Thu Apr 30 17:56:47 2009 -0400
@@ -372,10 +372,37 @@
 	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 @@
 		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 @@
 	if (--process->refcount > 0)
 		return TRUE;
 
+	i_assert(process->io_log_write == NULL);
 	i_assert(process->destroyed);
 
 	i_free(process);
@@ -543,7 +562,7 @@
 	   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);
 	}
--- a/src/master/service-process.h	Thu Apr 30 17:02:33 2009 -0400
+++ b/src/master/service-process.h	Thu Apr 30 17:56:47 2009 -0400
@@ -19,6 +19,8 @@
 
 	/* 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;
 };