]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Remove listener's IO earlier if possible
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 2 May 2017 15:39:06 +0000 (18:39 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Thu, 11 May 2017 13:13:12 +0000 (16:13 +0300)
This is needed for the next change to work properly.

src/lib-master/master-service.c

index 6aecbebad39591f9b5a53c5189e30421b0f53f34..776e62af907b422393263589eeeccb0a8966d58b 100644 (file)
@@ -716,6 +716,26 @@ void master_service_client_connection_created(struct master_service *service)
        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 @@ void master_service_client_connection_handled(struct master_service *service,
                   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);
+               }
        }
 }