]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Added master_service_stop_new_connections().
authorTimo Sirainen <tss@iki.fi>
Fri, 6 Nov 2009 18:56:10 +0000 (13:56 -0500)
committerTimo Sirainen <tss@iki.fi>
Fri, 6 Nov 2009 18:56:10 +0000 (13:56 -0500)
--HG--
branch : HEAD

src/lib-master/master-service-private.h
src/lib-master/master-service.c
src/lib-master/master-service.h

index 2ba018fb2f6f859f46c106bf3e77c1660d4e3851..9208b8748fd10501d1579d449a0003918a69d77b 100644 (file)
@@ -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;
index cc3e36310adc38ce53f46472bd492540fcbf6518..1af3af0568d261b649fb612626be811b0a89c97a 100644 (file)
@@ -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);
 
index 88a649073bbd32cab0a1f91e58f2de9aeb5e5c08..c62db6fb9590d95a632aac4177ebf1330467077b 100644 (file)
@@ -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);