Mercurial > dovecot > core-2.2
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);