changeset 10264:7bdb5816f797 HEAD

lib-master: Added master_service_stop_new_connections().
author Timo Sirainen <tss@iki.fi>
date Fri, 06 Nov 2009 13:56:10 -0500
parents 18f5fdeed659
children 8ebf82849077
files src/lib-master/master-service-private.h src/lib-master/master-service.c src/lib-master/master-service.h
diffstat 3 files changed, 32 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-master/master-service-private.h	Thu Nov 05 20:15:40 2009 -0500
+++ b/src/lib-master/master-service-private.h	Fri Nov 06 13:56:10 2009 -0500
@@ -47,6 +47,7 @@
 	const struct master_service_settings *set;
 	struct setting_parser_context *set_parser;
 
+	unsigned int stopping:1;
 	unsigned int keep_environment:1;
 	unsigned int log_directly:1;
 	unsigned int initial_status_sent:1;
--- a/src/lib-master/master-service.c	Thu Nov 05 20:15:40 2009 -0500
+++ b/src/lib-master/master-service.c	Fri Nov 06 13:56:10 2009 -0500
@@ -264,7 +264,7 @@
 
 static void master_service_error(struct master_service *service)
 {
-	master_service_io_listeners_remove(service);
+	master_service_stop_new_connections(service);
 	if (service->master_status.available_count ==
 	    service->total_available_count || service->die_with_master) {
 		if (service->die_callback == NULL)
@@ -470,6 +470,29 @@
         io_loop_stop(service->ioloop);
 }
 
+void master_service_stop_new_connections(struct master_service *service)
+{
+	unsigned int current_count;
+
+	service->stopping = TRUE;
+	master_service_io_listeners_remove(service);
+
+	/* make sure we stop after servicing current connections */
+	current_count = service->total_available_count -
+		service->master_status.available_count;
+	service->service_count_left = current_count;
+	service->total_available_count = current_count;
+
+	if (current_count == 0)
+		master_service_stop(service);
+	else {
+		/* notify master that we're not accepting any more
+		   connections */
+		service->master_status.available_count = 0;
+		master_status_update(service);
+	}
+}
+
 void master_service_anvil_send(struct master_service *service, const char *cmd)
 {
 	ssize_t ret;
@@ -504,6 +527,7 @@
 		i_assert(service->master_status.available_count <
 			 service->total_available_count);
 		service->master_status.available_count++;
+		master_status_update(service);
 	} else {
 		/* we have only limited amount of service requests left */
 		i_assert(service->service_count_left > 0);
@@ -516,7 +540,6 @@
 			master_service_stop(service);
 		}
 	}
-	master_status_update(service);
 
 	if ((service->io_status_error == NULL || service->listeners == NULL) &&
 	    service->master_status.available_count ==
@@ -702,6 +725,9 @@
 {
 	unsigned int i;
 
+	if (service->stopping)
+		return;
+
 	if (service->listeners == NULL)
 		io_listeners_init(service);
 
--- a/src/lib-master/master-service.h	Thu Nov 05 20:15:40 2009 -0500
+++ b/src/lib-master/master-service.h	Fri Nov 06 13:56:10 2009 -0500
@@ -105,6 +105,9 @@
 			master_service_connection_callback_t *callback);
 /* Stop a running service. */
 void master_service_stop(struct master_service *service);
+/* Stop once we're done serving existing new connections, but don't accept
+   any new ones. */
+void master_service_stop_new_connections(struct master_service *service);
 
 /* Send command to anvil process, if we have fd to it. */
 void master_service_anvil_send(struct master_service *service, const char *cmd);