]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Change master_service_set_avail_overflow_callback() API
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Jan 2020 17:10:43 +0000 (19:10 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Tue, 16 Mar 2021 17:00:06 +0000 (17:00 +0000)
Needed by the following changes.

src/lib-master/master-service-private.h
src/lib-master/master-service.c
src/lib-master/master-service.h
src/login-common/client-common.c
src/login-common/client-common.h

index d8a2da6bf368380673ccb314581bd49a856c8ad5..21c9bbe746d9cd81e6c1b335271e42a71dfe2b39 100644 (file)
@@ -57,7 +57,7 @@ struct master_service {
        void (*die_callback)(void);
        struct timeout *to_die;
 
-       void (*avail_overflow_callback)(void);
+       master_service_avail_overflow_callback_t *avail_overflow_callback;
        struct timeout *to_overflow_state;
 
        struct master_login *login;
index 2f2c94e78f3746c1d45b8d8e9081d472792d6337..2165384bec7d2e9321f527c05725cbeb18ea75e3 100644 (file)
@@ -828,7 +828,7 @@ const char *master_service_get_socket_name(struct master_service *service,
 }
 
 void master_service_set_avail_overflow_callback(struct master_service *service,
-                                               void (*callback)(void))
+       master_service_avail_overflow_callback_t *callback)
 {
        service->avail_overflow_callback = callback;
 }
@@ -1174,13 +1174,14 @@ static void master_service_listen(struct master_service_listener *l)
 {
        struct master_service *service = l->service;
        struct master_service_connection conn;
+       struct timeval created;
 
        if (service->master_status.available_count == 0) {
                /* we are full. stop listening for now, unless overflow
                   callback destroys one of the existing connections */
                if (service->call_avail_overflow &&
                    service->avail_overflow_callback != NULL)
-                       service->avail_overflow_callback();
+                       service->avail_overflow_callback(TRUE, &created);
 
                if (service->master_status.available_count == 0) {
                        master_service_io_listeners_remove(service);
index 044545f1e608066cf263340a50462c79cf0d672a..5d6fa875e81ac64f4769cb2c979fa6cbee6f6ea7 100644 (file)
@@ -94,6 +94,13 @@ struct master_service_connection {
 typedef void
 master_service_connection_callback_t(struct master_service_connection *conn);
 
+/* If kill==TRUE, the callback should kill one of the existing connections
+   (likely the oldest). If kill==FALSE, it's just a request to check what is
+   the creation timestamp for the connection to be killed. Returns TRUE if
+   a connection was/could be killed, FALSE if not. */
+typedef bool
+master_service_avail_overflow_callback_t(bool kill, struct timeval *created_r);
+
 extern struct master_service *master_service;
 
 const char *master_service_getopt_string(void);
@@ -157,10 +164,9 @@ void master_service_set_die_callback(struct master_service *service,
 void master_service_set_idle_die_callback(struct master_service *service,
                                          bool (*callback)(void));
 /* Call the given callback when there are no available connections and master
-   has indicated that it can't create any more processes to handle requests.
-   The callback could decide to kill one of the existing connections. */
+   has indicated that it can't create any more processes to handle requests. */
 void master_service_set_avail_overflow_callback(struct master_service *service,
-                                               void (*callback)(void));
+       master_service_avail_overflow_callback_t *callback);
 
 /* Set maximum number of clients we can handle. Default is given by master. */
 void master_service_set_client_limit(struct master_service *service,
index 5dfcbd95c496d695b75ca5eef223e9e781c1f47d..d73e796b480f7a93c8f91e4cbb21d7d14f2e0ccc 100644 (file)
@@ -437,13 +437,13 @@ void client_common_default_free(struct client *client ATTR_UNUSED)
 {
 }
 
-void client_destroy_oldest(void)
+bool client_destroy_oldest(bool kill, struct timeval *created_r)
 {
        struct client *client;
 
        if (last_client == NULL) {
                /* we have no clients */
-               return;
+               return FALSE;
        }
 
        /* destroy the last client that hasn't successfully authenticated yet.
@@ -456,9 +456,14 @@ void client_destroy_oldest(void)
        if (client == NULL)
                client = last_client;
 
+       *created_r = client->created;
+       if (!kill)
+               return TRUE;
+
        client_notify_disconnect(client, CLIENT_DISCONNECT_RESOURCE_CONSTRAINT,
                                 "Connection queue full");
        client_destroy(client, "Connection queue full");
+       return TRUE;
 }
 
 void clients_destroy_all_reason(const char *reason)
index 790762410d7f50c5c9e9b0b7274b37bad533083e..cc1d46826af7963056c19ca63b2583dc6df69447 100644 (file)
@@ -339,7 +339,7 @@ void client_proxy_log_failure(struct client *client, const char *line);
 const char *client_proxy_get_state(struct client *client);
 
 void clients_notify_auth_connected(void);
-void client_destroy_oldest(void);
+bool client_destroy_oldest(bool kill, struct timeval *created_r);
 void clients_destroy_all(void);
 void clients_destroy_all_reason(const char *reason);