/* Each server will have one occurrence of this structure per thread */
struct srv_per_thread {
+ struct mt_list streams; /* streams using this server (used by "shutdown server sessions") */
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 be_counters counters; /* statistics counters */
struct eb_root pendconns; /* pending connections */
- struct mt_list actconns; /* active connections (used by "shutdown server sessions") */
- struct srv_per_thread *per_thr; /* array of per-thread stuff such as connections lists, may be null */
+ struct srv_per_thread *per_thr; /* array of per-thread stuff such as connections lists */
unsigned int pool_purge_delay; /* Delay before starting to purge the idle conns pool */
unsigned int low_idle_conns; /* min idle connection count to start picking from other threads */
unsigned int max_idle_conns; /* Max number of connection allowed in the orphan connections list */
* from a conflict with an adjacent MT_LIST_DEL, and using it improves
* the performance by about 3% on 32-cores.
*/
- MT_LIST_ADD(&srv->actconns, &sess->by_srv);
+ MT_LIST_ADD(&srv->per_thr[tid].streams, &sess->by_srv);
HA_ATOMIC_STORE(&sess->srv_conn, srv);
}
newsrv->per_thr[i].idle_conns = EB_ROOT;
newsrv->per_thr[i].safe_conns = EB_ROOT;
newsrv->per_thr[i].avail_conns = EB_ROOT;
+ MT_LIST_INIT(&newsrv->per_thr[i].streams);
}
if (newsrv->max_idle_conns != 0) {
socket_tcp.next = NULL;
socket_tcp.proxy = &socket_proxy;
socket_tcp.obj_type = OBJ_TYPE_SERVER;
- MT_LIST_INIT(&socket_tcp.actconns);
socket_tcp.pendconns = EB_ROOT;
LIST_ADD(&servers_list, &socket_tcp.global_list);
socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
socket_ssl.next = NULL;
socket_ssl.proxy = &socket_proxy;
socket_ssl.obj_type = OBJ_TYPE_SERVER;
- MT_LIST_INIT(&socket_ssl.actconns);
socket_ssl.pendconns = EB_ROOT;
LIST_ADD(&servers_list, &socket_ssl.global_list);
socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
{
struct stream *stream;
struct mt_list *elt1, elt2;
+ int thr;
- mt_list_for_each_entry_safe(stream, &srv->actconns, by_srv, elt1, elt2)
- if (stream->srv_conn == srv)
- stream_shutdown(stream, why);
+ for (thr = 0; thr < global.nbthread; thr++)
+ mt_list_for_each_entry_safe(stream, &srv->per_thr[thr].streams, by_srv, elt1, elt2)
+ if (stream->srv_conn == srv)
+ stream_shutdown(stream, why);
}
/* Shutdown all connections of all backup servers of a proxy. The caller must
srv->obj_type = OBJ_TYPE_SERVER;
srv->proxy = proxy;
- MT_LIST_INIT(&srv->actconns);
srv->pendconns = EB_ROOT;
LIST_ADDQ(&servers_list, &srv->global_list);