unsigned int curr_total_conns; /* Current number of total connections to the server, used or idle, only calculated if strict-maxconn is used */
unsigned int max_used_conns; /* Max number of used connections (the counter is reset at each connection purges */
unsigned int est_need_conns; /* Estimate on the number of needed connections (max of curr and previous max_used) */
+ unsigned int curr_sess_idle_conns; /* Current number of idle connections attached to a session instead of idle/safe trees. */
/* Element below are usd by LB algorithms and must be doable in
* parallel to other threads reusing connections above.
if (obj_type(conn->target) == OBJ_TYPE_SERVER) {
struct server *srv = __objt_server(conn->target);
- /* If the connection is not private, it is accounted by the server. */
- if (!(conn->flags & CO_FL_PRIVATE)) {
+ if (!(conn->flags & CO_FL_PRIVATE) || (conn->flags & CO_FL_SESS_IDLE))
srv_release_conn(srv, conn);
- }
+
if (srv->flags & SRV_F_STRICT_MAXCONN)
_HA_ATOMIC_DEC(&srv->curr_total_conns);
}
/* removes an idle conn after updating the server idle conns counters */
void srv_release_conn(struct server *srv, struct connection *conn)
{
- if (conn->flags & CO_FL_LIST_MASK) {
+ if (conn->flags & CO_FL_SESS_IDLE) {
+ _HA_ATOMIC_DEC(&srv->curr_sess_idle_conns);
+ conn->flags &= ~CO_FL_SESS_IDLE;
+ }
+ else 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.
*/
list_for_each_entry_safe(conn, conn_back, &pconns->conn_list, sess_el) {
LIST_DEL_INIT(&conn->sess_el);
conn->owner = NULL;
- conn->flags &= ~CO_FL_SESS_IDLE;
LIST_APPEND(&conn_tmp_list, &conn->sess_el);
}
MT_LIST_DELETE(&pconns->srv_el);
/* Check that session <sess> is able to keep idle connection <conn>. This must
* be called each time a connection stored in a session becomes idle.
*
+ * If <conn> can be kept as idle in the session, idle sess conn counter of its
+ * target server will be incremented.
+ *
* Returns 0 if the connection is kept, else non-zero if the connection was
* explicitely removed from session.
*/
else {
conn->flags |= CO_FL_SESS_IDLE;
sess->idle_conns++;
+ if (srv)
+ HA_ATOMIC_INC(&srv->curr_sess_idle_conns);
}
return 0;
{
struct connection *srv_conn, *res = NULL;
struct sess_priv_conns *pconns;
+ struct server *srv;
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
if (srv_conn->flags & CO_FL_SESS_IDLE) {
srv_conn->flags &= ~CO_FL_SESS_IDLE;
sess->idle_conns--;
+
+ srv = objt_server(srv_conn->target);
+ if (srv)
+ HA_ATOMIC_DEC(&srv->curr_sess_idle_conns);
}
res = srv_conn;