changeset 22026:7835a8a35d66

lib-master: Remove listener's IO earlier if possible This is needed for the next change to work properly.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 02 May 2017 18:39:06 +0300
parents 1248ad7e16cd
children 38826e486570
files src/lib-master/master-service.c
diffstat 1 files changed, 29 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-master/master-service.c	Tue May 02 15:56:40 2017 +0300
+++ b/src/lib-master/master-service.c	Tue May 02 18:39:06 2017 +0300
@@ -716,6 +716,26 @@
 	master_status_update(service);
 }
 
+static bool master_service_want_listener(struct master_service *service)
+{
+	if (service->master_status.available_count > 0) {
+		/* more concurrent clients can still be added */
+		return TRUE;
+	}
+	if (service->service_count_left == 1) {
+		/* after handling this client, the whole process will stop. */
+		return FALSE;
+	}
+	if (service->avail_overflow_callback != NULL) {
+		/* overflow callback is set. it's possible that the current
+		   existing client may be replaced by a new client, which needs
+		   the listener to try to accept new connections. */
+		return TRUE;
+	}
+	/* the listener isn't needed until the current client is disconnected */
+	return FALSE;
+}
+
 void master_service_client_connection_handled(struct master_service *service,
 					      struct master_service_connection *conn)
 {
@@ -728,15 +748,17 @@
 		   as real clients */
 		master_service_client_connection_destroyed(service);
 	}
-	if (service->master_status.available_count == 0 &&
-	    service->service_count_left == 1) {
-		/* we're not going to accept any more connections after this.
-		   go ahead and close the connection early. don't do this
-		   before calling callback, because it may want to access
-		   the listen_fd (e.g. to check socket permissions). */
+	if (!master_service_want_listener(service)) {
 		i_assert(service->listeners != NULL);
 		master_service_io_listeners_remove(service);
-		master_service_io_listeners_close(service);
+		if (service->service_count_left == 1) {
+			/* we're not going to accept any more connections after
+			   this. go ahead and close the connection early. don't
+			   do this before calling callback, because it may want
+			   to access the listen_fd (e.g. to check socket
+			   permissions). */
+			master_service_io_listeners_close(service);
+		}
 	}
 }