MINOR: srv: close all idle connections on shutdown
Implement a function to close all server idle connections. This function
is called via a global deinit server handler.
The main objective is to prevents from leaving sockets in TIME_WAIT
state. To limit the set of operations on shutdown and prevents
tasks rescheduling, only the ctrl stack closing is done.
diff --git a/src/server.c b/src/server.c
index 60e76a6..07e82ad 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5317,6 +5317,43 @@
return task;
}
+/* Close remaining idle connections. This functions is designed to be run on
+ * process shutdown. This guarantees a proper socket shutdown to avoid
+ * TIME_WAIT state. For a quick operation, only ctrl is closed, xprt stack is
+ * bypassed.
+ *
+ * This function is not thread-safe so it must only be called via a global
+ * deinit function.
+ */
+static void srv_close_idle_conns(struct server *srv)
+{
+ struct eb_root **cleaned_tree;
+ int i;
+
+ for (i = 0; i < global.nbthread; ++i) {
+ struct eb_root *conn_trees[] = {
+ &srv->per_thr[i].idle_conns,
+ &srv->per_thr[i].safe_conns,
+ &srv->per_thr[i].avail_conns,
+ NULL
+ };
+
+ for (cleaned_tree = conn_trees; *cleaned_tree; ++cleaned_tree) {
+ while (!eb_is_empty(*cleaned_tree)) {
+ struct ebmb_node *node = ebmb_first(*cleaned_tree);
+ struct conn_hash_node *conn_hash_node = ebmb_entry(node, struct conn_hash_node, node);
+ struct connection *conn = conn_hash_node->conn;
+
+ if (conn->ctrl->ctrl_close)
+ conn->ctrl->ctrl_close(conn);
+ ebmb_delete(node);
+ }
+ }
+ }
+}
+
+REGISTER_SERVER_DEINIT(srv_close_idle_conns);
+
/* config parser for global "tune.idle-pool.shared", accepts "on" or "off" */
static int cfg_parse_idle_pool_shared(char **args, int section_type, struct proxy *curpx,
const struct proxy *defpx, const char *file, int line,