diff --git a/include/types/server.h b/include/types/server.h index 69397c1ca..ecf04d7c9 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -207,9 +207,9 @@ struct server { struct list pendconns; /* pending connections */ struct list actconns; /* active connections */ - struct list priv_conns; /* private idle connections attached to stream interfaces */ - struct list idle_conns; /* sharable idle connections attached or not to a stream interface */ - struct list safe_conns; /* safe idle connections attached to stream interfaces, shared */ + struct list *priv_conns; /* private idle connections attached to stream interfaces */ + struct list *idle_conns; /* sharable idle connections attached or not to a stream interface */ + struct list *safe_conns; /* safe idle connections attached to stream interfaces, shared */ struct task *warmup; /* the task dedicated to the warmup when slowstart is set */ struct conn_src conn_src; /* connection source settings */ diff --git a/src/backend.c b/src/backend.c index 475efa36d..5e51f39ea 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1066,20 +1066,19 @@ int connect_server(struct stream *s) * idle| - | 1 | idle| - | 1 | idle| 2 | 1 | * ----+-----+-----+ ----+-----+-----+ ----+-----+-----+ */ - - if (!LIST_ISEMPTY(&srv->idle_conns) && + if (srv->idle_conns && !LIST_ISEMPTY(&srv->idle_conns[tid]) && ((s->be->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR && s->txn && (s->txn->flags & TX_NOT_FIRST))) { - srv_conn = LIST_ELEM(srv->idle_conns.n, struct connection *, list); + srv_conn = LIST_ELEM(srv->idle_conns[tid].n, struct connection *, list); } - else if (!LIST_ISEMPTY(&srv->safe_conns) && + else if (srv->safe_conns && !LIST_ISEMPTY(&srv->safe_conns[tid]) && ((s->txn && (s->txn->flags & TX_NOT_FIRST)) || (s->be->options & PR_O_REUSE_MASK) >= PR_O_REUSE_AGGR)) { - srv_conn = LIST_ELEM(srv->safe_conns.n, struct connection *, list); + srv_conn = LIST_ELEM(srv->safe_conns[tid].n, struct connection *, list); } - else if (!LIST_ISEMPTY(&srv->idle_conns) && + else if (srv->idle_conns && !LIST_ISEMPTY(&srv->idle_conns[tid]) && (s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS) { - srv_conn = LIST_ELEM(srv->idle_conns.n, struct connection *, list); + srv_conn = LIST_ELEM(srv->idle_conns[tid].n, struct connection *, list); } /* If we've picked a connection from the pool, we now have to diff --git a/src/hlua.c b/src/hlua.c index 137117c58..36b1b3ff4 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -7666,9 +7666,9 @@ void hlua_init(void) socket_tcp.obj_type = OBJ_TYPE_SERVER; LIST_INIT(&socket_tcp.actconns); LIST_INIT(&socket_tcp.pendconns); - LIST_INIT(&socket_tcp.priv_conns); - LIST_INIT(&socket_tcp.idle_conns); - LIST_INIT(&socket_tcp.safe_conns); + socket_tcp.priv_conns = NULL; + socket_tcp.idle_conns = NULL; + socket_tcp.safe_conns = NULL; socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */ socket_tcp.last_change = 0; socket_tcp.id = "LUA-TCP-CONN"; @@ -7712,9 +7712,9 @@ void hlua_init(void) socket_ssl.obj_type = OBJ_TYPE_SERVER; LIST_INIT(&socket_ssl.actconns); LIST_INIT(&socket_ssl.pendconns); - LIST_INIT(&socket_ssl.priv_conns); - LIST_INIT(&socket_ssl.idle_conns); - LIST_INIT(&socket_ssl.safe_conns); + socket_tcp.priv_conns = NULL; + socket_tcp.idle_conns = NULL; + socket_tcp.safe_conns = NULL; socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */ socket_ssl.last_change = 0; socket_ssl.id = "LUA-SSL-CONN"; diff --git a/src/proto_http.c b/src/proto_http.c index cfc0e7285..cf1cc7af2 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -4348,15 +4348,15 @@ void http_end_txn_clean_session(struct stream *s) if (!srv) si_idle_conn(&s->si[1], NULL); else if (srv_conn->flags & CO_FL_PRIVATE) - si_idle_conn(&s->si[1], &srv->priv_conns); + si_idle_conn(&s->si[1], (srv->priv_conns ? &srv->priv_conns[tid] : NULL)); else if (prev_flags & TX_NOT_FIRST) /* note: we check the request, not the connection, but * this is valid for strategies SAFE and AGGR, and in * case of ALWS, we don't care anyway. */ - si_idle_conn(&s->si[1], &srv->safe_conns); + si_idle_conn(&s->si[1], (srv->safe_conns ? &srv->safe_conns[tid] : NULL)); else - si_idle_conn(&s->si[1], &srv->idle_conns); + si_idle_conn(&s->si[1], (srv->idle_conns ? &srv->idle_conns[tid] : NULL)); } s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0; s->res.analysers = 0; diff --git a/src/server.c b/src/server.c index 01a7d9b67..4c70ac4ad 100644 --- a/src/server.c +++ b/src/server.c @@ -1511,6 +1511,7 @@ static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmp static struct server *new_server(struct proxy *proxy) { struct server *srv; + int i; srv = calloc(1, sizeof *srv); if (!srv) @@ -1520,9 +1521,20 @@ static struct server *new_server(struct proxy *proxy) srv->proxy = proxy; LIST_INIT(&srv->actconns); LIST_INIT(&srv->pendconns); - LIST_INIT(&srv->priv_conns); - LIST_INIT(&srv->idle_conns); - LIST_INIT(&srv->safe_conns); + + if ((srv->priv_conns = calloc(global.nbthread, sizeof(*srv->priv_conns))) == NULL) + goto free_srv; + if ((srv->idle_conns = calloc(global.nbthread, sizeof(*srv->idle_conns))) == NULL) + goto free_priv_conns; + if ((srv->safe_conns = calloc(global.nbthread, sizeof(*srv->safe_conns))) == NULL) + goto free_idle_conns; + + for (i = 0; i < global.nbthread; i++) { + LIST_INIT(&srv->priv_conns[i]); + LIST_INIT(&srv->idle_conns[i]); + LIST_INIT(&srv->safe_conns[i]); + } + LIST_INIT(&srv->update_status); srv->next_state = SRV_ST_RUNNING; /* early server setup */ @@ -1537,6 +1549,14 @@ static struct server *new_server(struct proxy *proxy) srv->xprt = srv->check.xprt = srv->agent.xprt = xprt_get(XPRT_RAW); return srv; + + free_idle_conns: + free(srv->idle_conns); + free_priv_conns: + free(srv->priv_conns); + free_srv: + free(srv); + return NULL; } /*