From 275385a2ecc58e41dc7df3ce3cd943caaa58c4d1 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 6 Nov 2009 13:56:10 -0500 Subject: [PATCH] lib-master: Added master_service_stop_new_connections(). --HG-- branch : HEAD --- src/lib-master/master-service-private.h | 1 + src/lib-master/master-service.c | 30 +++++++++++++++++++++++-- src/lib-master/master-service.h | 3 +++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/lib-master/master-service-private.h b/src/lib-master/master-service-private.h index 2ba018fb2f..9208b8748f 100644 --- a/src/lib-master/master-service-private.h +++ b/src/lib-master/master-service-private.h @@ -47,6 +47,7 @@ struct master_service { 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; diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index cc3e36310a..1af3af0568 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -264,7 +264,7 @@ bool master_service_parse_option(struct master_service *service, 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 @@ void master_service_stop(struct master_service *service) 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 @@ void master_service_client_connection_destroyed(struct master_service *service) 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 @@ void master_service_client_connection_destroyed(struct master_service *service) 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 @@ void master_service_io_listeners_add(struct master_service *service) { unsigned int i; + if (service->stopping) + return; + if (service->listeners == NULL) io_listeners_init(service); diff --git a/src/lib-master/master-service.h b/src/lib-master/master-service.h index 88a649073b..c62db6fb95 100644 --- a/src/lib-master/master-service.h +++ b/src/lib-master/master-service.h @@ -105,6 +105,9 @@ void master_service_run(struct master_service *service, 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); -- 2.47.3