From: Timo Sirainen Date: Fri, 6 Nov 2009 18:56:10 +0000 (-0500) Subject: lib-master: Added master_service_stop_new_connections(). X-Git-Tag: 2.0.alpha3~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=275385a2ecc58e41dc7df3ce3cd943caaa58c4d1;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Added master_service_stop_new_connections(). --HG-- branch : HEAD --- 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);