changeset 12723:b399f91ae660

master: If process limit is reached, just accept and close the client connection. This makes it a bit clearer what the problem is, so that client can log a better error message.
author Timo Sirainen <tss@iki.fi>
date Tue, 08 Feb 2011 03:31:01 +0200
parents 888999441619
children 443cc3044d91
files src/master/service-monitor.c
diffstat 1 files changed, 19 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/master/service-monitor.c	Mon Feb 07 22:37:45 2011 +0200
+++ b/src/master/service-monitor.c	Tue Feb 08 03:31:01 2011 +0200
@@ -195,8 +195,11 @@
 	service_throttle(service, SERVICE_STARTUP_FAILURE_THROTTLE_SECS);
 }
 
-static void service_drop_connections(struct service *service)
+static void service_drop_connections(struct service_listener *l)
 {
+	struct service *service = l->service;
+	int fd;
+
 	if (service->last_drop_warning +
 	    SERVICE_DROP_WARN_INTERVAL_SECS < ioloop_time) {
 		service->last_drop_warning = ioloop_time;
@@ -206,25 +209,35 @@
 			  service->process_limit > 1 ?
 			  "process_limit" : "client_limit");
 	}
-	service->listen_pending = TRUE;
-	service_monitor_listen_stop(service);
 
 	if (service->type == SERVICE_TYPE_LOGIN) {
 		/* reached process limit, notify processes that they
 		   need to start killing existing connections if they
 		   reach connection limit */
 		service_login_notify(service, TRUE);
+
+		service->listen_pending = TRUE;
+		service_monitor_listen_stop(service);
+	} else {
+		/* just accept and close the connection, so it's clear that
+		   this is happening because of the limit, rather than because
+		   the service processes aren't answering fast enough */
+		fd = net_accept(l->fd, NULL, NULL);
+		if (fd > 0)
+			net_disconnect(fd);
 	}
 }
 
-static void service_accept(struct service *service)
+static void service_accept(struct service_listener *l)
 {
+	struct service *service = l->service;
+
 	i_assert(service->process_avail == 0);
 
 	if (service->process_count == service->process_limit) {
 		/* we've reached our limits, new clients will have to
 		   wait until there are more processes available */
-		service_drop_connections(service);
+		service_drop_connections(l);
 		return;
 	}
 
@@ -274,7 +287,7 @@
 		struct service_listener *l = *listeners;
 
 		if (l->io == NULL && l->fd != -1)
-			l->io = io_add(l->fd, IO_READ, service_accept, service);
+			l->io = io_add(l->fd, IO_READ, service_accept, l);
 	}
 }