struct eb_root idle_conns; /* Shareable idle connections */
struct eb_root safe_conns; /* Safe idle connections */
struct eb_root avail_conns; /* Connections in use, but with still new streams available */
+ struct mt_list sess_conns; /* Connections attached to a session which cannot be shared across clients */
/* Secondary idle conn storage used in parallel to idle/safe trees.
* Used to sort them by last usage and purge them in reverse order.
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) */
- struct mt_list sess_conns; /* list of private conns managed by a session on this server */
-
/* Element below are usd by LB algorithms and must be doable in
* parallel to other threads reusing connections above.
*/
srv->agent.proxy = proxy;
srv->xprt = srv->check.xprt = srv->agent.xprt = xprt_get(XPRT_RAW);
- MT_LIST_INIT(&srv->sess_conns);
-
guid_init(&srv->guid);
MT_LIST_INIT(&srv->watcher_list);
srv->per_thr[i].idle_conns = EB_ROOT;
srv->per_thr[i].safe_conns = EB_ROOT;
srv->per_thr[i].avail_conns = EB_ROOT;
+ MT_LIST_INIT(&srv->per_thr[i].sess_conns);
MT_LIST_INIT(&srv->per_thr[i].streams);
LIST_INIT(&srv->per_thr[i].idle_conn_list);
BUG_ON(srv->curr_idle_conns);
/* Close idle private connections attached to this server. */
- MT_LIST_FOR_EACH_ENTRY_LOCKED(sess_conns, &srv->sess_conns, srv_el, back) {
- struct connection *conn, *conn_back;
- list_for_each_entry_safe(conn, conn_back, &sess_conns->conn_list, sess_el) {
-
- /* Only idle connections should be present if srv_check_for_deletion() is true. */
- BUG_ON(!(conn->flags & CO_FL_SESS_IDLE));
- --((struct session *)conn->owner)->idle_conns;
-
- LIST_DEL_INIT(&conn->sess_el);
- conn->owner = NULL;
-
- if (sess_conns->tid != tid) {
- if (conn->mux && conn->mux->takeover)
- conn->mux->takeover(conn, sess_conns->tid, 1);
- else if (conn->xprt && conn->xprt->takeover)
- conn->xprt->takeover(conn, conn->ctx, sess_conns->tid, 1);
+ for (i = tid;;) {
+ MT_LIST_FOR_EACH_ENTRY_LOCKED(sess_conns, &srv->per_thr[i].sess_conns, srv_el, back) {
+ struct connection *conn, *conn_back;
+ list_for_each_entry_safe(conn, conn_back, &sess_conns->conn_list, sess_el) {
+
+ /* Only idle connections should be present if srv_check_for_deletion() is true. */
+ BUG_ON(!(conn->flags & CO_FL_SESS_IDLE));
+ --((struct session *)conn->owner)->idle_conns;
+
+ LIST_DEL_INIT(&conn->sess_el);
+ conn->owner = NULL;
+
+ if (sess_conns->tid != tid) {
+ if (conn->mux && conn->mux->takeover)
+ conn->mux->takeover(conn, sess_conns->tid, 1);
+ else if (conn->xprt && conn->xprt->takeover)
+ conn->xprt->takeover(conn, conn->ctx, sess_conns->tid, 1);
+ }
+ conn_release(conn);
}
- conn_release(conn);
+
+ LIST_DELETE(&sess_conns->sess_el);
+ pool_free(pool_head_sess_priv_conns, sess_conns);
+ sess_conns = NULL;
}
- LIST_DELETE(&sess_conns->sess_el);
- pool_free(pool_head_sess_priv_conns, sess_conns);
- sess_conns = NULL;
+ if ((i = ((i + 1 == global.nbthread) ? 0 : i + 1)) == tid)
+ break;
}
/* removing cannot fail anymore when we reach this: