mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
MEDIUM: threads/server: Make connection list (priv/idle/safe) thread-safe
For now, we have a list of each type per thread. So there is no need to lock them. This is the easiest solution for now, but not the best one because there is no sharing between threads. An idle connection on a thread will not be able be used by a stream on another thread. So it could be a good idea to rework this patch later.
This commit is contained in:
parent
ff8abcd31d
commit
40a007cf2a
@ -207,9 +207,9 @@ struct server {
|
|||||||
|
|
||||||
struct list pendconns; /* pending connections */
|
struct list pendconns; /* pending connections */
|
||||||
struct list actconns; /* active connections */
|
struct list actconns; /* active connections */
|
||||||
struct list priv_conns; /* private idle connections attached to stream interfaces */
|
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 *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 *safe_conns; /* safe idle connections attached to stream interfaces, shared */
|
||||||
struct task *warmup; /* the task dedicated to the warmup when slowstart is set */
|
struct task *warmup; /* the task dedicated to the warmup when slowstart is set */
|
||||||
|
|
||||||
struct conn_src conn_src; /* connection source settings */
|
struct conn_src conn_src; /* connection source settings */
|
||||||
|
@ -1066,20 +1066,19 @@ int connect_server(struct stream *s)
|
|||||||
* idle| - | 1 | idle| - | 1 | idle| 2 | 1 |
|
* idle| - | 1 | idle| - | 1 | idle| 2 | 1 |
|
||||||
* ----+-----+-----+ ----+-----+-----+ ----+-----+-----+
|
* ----+-----+-----+ ----+-----+-----+ ----+-----+-----+
|
||||||
*/
|
*/
|
||||||
|
if (srv->idle_conns && !LIST_ISEMPTY(&srv->idle_conns[tid]) &&
|
||||||
if (!LIST_ISEMPTY(&srv->idle_conns) &&
|
|
||||||
((s->be->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR &&
|
((s->be->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR &&
|
||||||
s->txn && (s->txn->flags & TX_NOT_FIRST))) {
|
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->txn && (s->txn->flags & TX_NOT_FIRST)) ||
|
||||||
(s->be->options & PR_O_REUSE_MASK) >= PR_O_REUSE_AGGR)) {
|
(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) {
|
(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
|
/* If we've picked a connection from the pool, we now have to
|
||||||
|
12
src/hlua.c
12
src/hlua.c
@ -7666,9 +7666,9 @@ void hlua_init(void)
|
|||||||
socket_tcp.obj_type = OBJ_TYPE_SERVER;
|
socket_tcp.obj_type = OBJ_TYPE_SERVER;
|
||||||
LIST_INIT(&socket_tcp.actconns);
|
LIST_INIT(&socket_tcp.actconns);
|
||||||
LIST_INIT(&socket_tcp.pendconns);
|
LIST_INIT(&socket_tcp.pendconns);
|
||||||
LIST_INIT(&socket_tcp.priv_conns);
|
socket_tcp.priv_conns = NULL;
|
||||||
LIST_INIT(&socket_tcp.idle_conns);
|
socket_tcp.idle_conns = NULL;
|
||||||
LIST_INIT(&socket_tcp.safe_conns);
|
socket_tcp.safe_conns = NULL;
|
||||||
socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
|
socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
|
||||||
socket_tcp.last_change = 0;
|
socket_tcp.last_change = 0;
|
||||||
socket_tcp.id = "LUA-TCP-CONN";
|
socket_tcp.id = "LUA-TCP-CONN";
|
||||||
@ -7712,9 +7712,9 @@ void hlua_init(void)
|
|||||||
socket_ssl.obj_type = OBJ_TYPE_SERVER;
|
socket_ssl.obj_type = OBJ_TYPE_SERVER;
|
||||||
LIST_INIT(&socket_ssl.actconns);
|
LIST_INIT(&socket_ssl.actconns);
|
||||||
LIST_INIT(&socket_ssl.pendconns);
|
LIST_INIT(&socket_ssl.pendconns);
|
||||||
LIST_INIT(&socket_ssl.priv_conns);
|
socket_tcp.priv_conns = NULL;
|
||||||
LIST_INIT(&socket_ssl.idle_conns);
|
socket_tcp.idle_conns = NULL;
|
||||||
LIST_INIT(&socket_ssl.safe_conns);
|
socket_tcp.safe_conns = NULL;
|
||||||
socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
|
socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
|
||||||
socket_ssl.last_change = 0;
|
socket_ssl.last_change = 0;
|
||||||
socket_ssl.id = "LUA-SSL-CONN";
|
socket_ssl.id = "LUA-SSL-CONN";
|
||||||
|
@ -4348,15 +4348,15 @@ void http_end_txn_clean_session(struct stream *s)
|
|||||||
if (!srv)
|
if (!srv)
|
||||||
si_idle_conn(&s->si[1], NULL);
|
si_idle_conn(&s->si[1], NULL);
|
||||||
else if (srv_conn->flags & CO_FL_PRIVATE)
|
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)
|
else if (prev_flags & TX_NOT_FIRST)
|
||||||
/* note: we check the request, not the connection, but
|
/* note: we check the request, not the connection, but
|
||||||
* this is valid for strategies SAFE and AGGR, and in
|
* this is valid for strategies SAFE and AGGR, and in
|
||||||
* case of ALWS, we don't care anyway.
|
* 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
|
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->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
|
||||||
s->res.analysers = 0;
|
s->res.analysers = 0;
|
||||||
|
26
src/server.c
26
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)
|
static struct server *new_server(struct proxy *proxy)
|
||||||
{
|
{
|
||||||
struct server *srv;
|
struct server *srv;
|
||||||
|
int i;
|
||||||
|
|
||||||
srv = calloc(1, sizeof *srv);
|
srv = calloc(1, sizeof *srv);
|
||||||
if (!srv)
|
if (!srv)
|
||||||
@ -1520,9 +1521,20 @@ static struct server *new_server(struct proxy *proxy)
|
|||||||
srv->proxy = proxy;
|
srv->proxy = proxy;
|
||||||
LIST_INIT(&srv->actconns);
|
LIST_INIT(&srv->actconns);
|
||||||
LIST_INIT(&srv->pendconns);
|
LIST_INIT(&srv->pendconns);
|
||||||
LIST_INIT(&srv->priv_conns);
|
|
||||||
LIST_INIT(&srv->idle_conns);
|
if ((srv->priv_conns = calloc(global.nbthread, sizeof(*srv->priv_conns))) == NULL)
|
||||||
LIST_INIT(&srv->safe_conns);
|
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);
|
LIST_INIT(&srv->update_status);
|
||||||
|
|
||||||
srv->next_state = SRV_ST_RUNNING; /* early server setup */
|
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);
|
srv->xprt = srv->check.xprt = srv->agent.xprt = xprt_get(XPRT_RAW);
|
||||||
|
|
||||||
return srv;
|
return srv;
|
||||||
|
|
||||||
|
free_idle_conns:
|
||||||
|
free(srv->idle_conns);
|
||||||
|
free_priv_conns:
|
||||||
|
free(srv->priv_conns);
|
||||||
|
free_srv:
|
||||||
|
free(srv);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user