From c6e7563b1aa77879a3da5a19e20ab39a7d75d4cb Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Thu, 2 Jul 2020 16:03:30 +0200 Subject: [PATCH] MINOR: server: Factorize code to deal with connections removed from an idle list The srv_del_conn_from_list() function is now responsible to update the server counters and the connection flags when a connection is removed from an idle list (safe, idle or available). It is called when a connection is released or when a connection is set as private. This function also removes the connection from the idle list if necessary. --- include/haproxy/connection.h | 38 ++++++++++++++---------------------- include/haproxy/server.h | 21 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 08f4313fe..a1740b98e 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -346,11 +346,12 @@ static inline void conn_set_owner(struct connection *conn, void *owner, void (*c /* Mark the connection as private and remove it from the available connection list */ static inline void conn_set_private(struct connection *conn) { - conn->flags |= CO_FL_PRIVATE; + if (!(conn->flags & CO_FL_PRIVATE)) { + conn->flags |= CO_FL_PRIVATE; - /* Be sure to remove the connection from the available_conns list */ - if (!MT_LIST_ISEMPTY(&conn->list)) - MT_LIST_DEL(&conn->list); + if (obj_type(conn->target) == OBJ_TYPE_SERVER) + srv_del_conn_from_list(__objt_server(conn->target), conn); + } } /* Allocates a struct sockaddr from the pool if needed, assigns it to *sap and @@ -464,9 +465,16 @@ static inline void conn_force_unsubscribe(struct connection *conn) /* Releases a connection previously allocated by conn_new() */ static inline void conn_free(struct connection *conn) { - /* Remove ourself from the session's connections list, if any. */ - if (!LIST_ISEMPTY(&conn->session_list)) { - session_unown_conn(conn->owner, conn); + if (conn->flags & CO_FL_PRIVATE) { + /* The connection is private, so remove it from the session's + * connections list, if any. + */ + if (!LIST_ISEMPTY(&conn->session_list)) + session_unown_conn(conn->owner, conn); + } + else { + if (obj_type(conn->target) == OBJ_TYPE_SERVER) + srv_del_conn_from_list(__objt_server(conn->target), conn); } sockaddr_free(&conn->src); @@ -488,23 +496,7 @@ static inline void conn_free(struct connection *conn) if (conn->ctx != NULL && conn->mux == NULL) *(void **)conn->ctx = NULL; - /* The connection is currently in the server's idle list, so tell it - * there's one less connection available in that list. - */ - if (conn->idle_time > 0) { - struct server *srv = __objt_server(conn->target); - _HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); - _HA_ATOMIC_SUB(conn->flags & CO_FL_SAFE_LIST ? &srv->curr_safe_nb : &srv->curr_idle_nb, 1); - _HA_ATOMIC_SUB(&srv->curr_idle_thr[tid], 1); - } else { - struct server *srv = objt_server(conn->target); - - if (srv) - _HA_ATOMIC_SUB(&srv->curr_used_conns, 1); - } - conn_force_unsubscribe(conn); - MT_LIST_DEL((struct mt_list *)&conn->list); pool_free(pool_head_connection, conn); } diff --git a/include/haproxy/server.h b/include/haproxy/server.h index 929eeba6f..5ed58373a 100644 --- a/include/haproxy/server.h +++ b/include/haproxy/server.h @@ -263,6 +263,27 @@ static inline void srv_use_idle_conn(struct server *srv, struct connection *conn srv->est_need_conns = srv->curr_used_conns; } +static inline void srv_del_conn_from_list(struct server *srv, struct connection *conn) +{ + if (conn->flags & CO_FL_LIST_MASK) { + /* The connection is currently in the server's idle list, so tell it + * there's one less connection available in that list. + */ + _HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); + _HA_ATOMIC_SUB(conn->flags & CO_FL_SAFE_LIST ? &srv->curr_safe_nb : &srv->curr_idle_nb, 1); + _HA_ATOMIC_SUB(&srv->curr_idle_thr[tid], 1); + } + else { + /* The connction is not private and not in any server's idle + * list, so decrement the current number of used connections + */ + _HA_ATOMIC_SUB(&srv->curr_used_conns, 1); + } + + /* Remove the connection from any list (safe, idle or available) */ + MT_LIST_DEL((struct mt_list *)&conn->list); +} + /* This adds an idle connection to the server's list if the connection is * reusable, not held by any owner anymore, but still has available streams. */