dovecot-2.0: master: If process limit is reached, just accept an...

dovecot at dovecot.org dovecot at dovecot.org
Tue Feb 8 03:31:48 EET 2011


details:   http://hg.dovecot.org/dovecot-2.0/rev/b399f91ae660
changeset: 12588:b399f91ae660
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 08 03:31:01 2011 +0200
description:
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.

diffstat:

 src/master/service-monitor.c |  25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)

diffs (65 lines):

diff -r 888999441619 -r b399f91ae660 src/master/service-monitor.c
--- 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);
 	}
 }
 


More information about the dovecot-cvs mailing list