dovecot-2.0: master: Fixed logging process related bugs.

dovecot at dovecot.org dovecot at dovecot.org
Fri May 1 00:56:53 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/2f293c844e31
changeset: 9182:2f293c844e31
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Apr 30 17:56:47 2009 -0400
description:
master: Fixed logging process related bugs.

diffstat:

3 files changed, 68 insertions(+), 28 deletions(-)
src/master/service-log.c     |   21 +++++++++++-
src/master/service-process.c |   73 ++++++++++++++++++++++++++----------------
src/master/service-process.h |    2 +

diffs (165 lines):

diff -r 150a98d2407c -r 2f293c844e31 src/master/service-log.c
--- 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 @@ int services_log_init(struct service_lis
 	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_
 			}
 			services[i]->log_fd[0] = -1;
 			services[i]->log_fd[1] = -1;
+			service_remove_log_io_writes(services[i]);
 		}
 	}
 }
diff -r 150a98d2407c -r 2f293c844e31 src/master/service-process.c
--- 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,30 +372,13 @@ service_process_create(struct service *s
 	return process;
 }
 
-void service_process_destroy(struct service_process *process)
-{
-	struct service *service = process->service;
+static void service_process_log_bye(struct service_process *process)
+{
 	const char *data;
 
-	hash_table_remove(service->list->pids, &process->pid);
-
-	if (process->available_count > 0)
-		service->process_avail--;
-	service->process_count--;
-	i_assert(service->process_avail <= service->process_count);
-
-	if (process->to_status != NULL)
-		timeout_remove(&process->to_status);
-
-	switch (process->service->type) {
-	case SERVICE_TYPE_AUTH_SERVER:
-		service_process_auth_server_deinit(process);
-		break;
-	case SERVICE_TYPE_AUTH_SOURCE:
-		service_process_auth_source_deinit(process);
-		break;
-	default:
-		break;
+	if (process->service->log_fd[1] == -1) {
+		/* stopping all services */
+		return;
 	}
 
 	data = t_strdup_printf("\001%c%s bye\n",
@@ -404,10 +387,45 @@ void service_process_destroy(struct serv
 		if (errno != EAGAIN)
 			i_error("write(log process) failed: %m");
 		else {
-			//FIXME:process->io_log_write = io_add();
-			//return;
-		}
-	}
+			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;
+
+	hash_table_remove(service->list->pids, &process->pid);
+
+	if (process->available_count > 0)
+		service->process_avail--;
+	service->process_count--;
+	i_assert(service->process_avail <= service->process_count);
+
+	if (process->to_status != NULL)
+		timeout_remove(&process->to_status);
+
+	switch (process->service->type) {
+	case SERVICE_TYPE_AUTH_SERVER:
+		service_process_auth_server_deinit(process);
+		break;
+	case SERVICE_TYPE_AUTH_SOURCE:
+		service_process_auth_source_deinit(process);
+		break;
+	default:
+		break;
+	}
+
+	service_process_log_bye(process);
 
 	process->destroyed = TRUE;
 	service_process_unref(process);
@@ -427,6 +445,7 @@ int service_process_unref(struct service
 	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 s
 	   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);
 	}
diff -r 150a98d2407c -r 2f293c844e31 src/master/service-process.h
--- 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 @@ 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;
 };


More information about the dovecot-cvs mailing list