MEDIUM: mux: Destroy the stream before trying to add the conn to the idle list.

In the mux_h1 and mux_h2, move the test to see if we should add the
connection in the idle list until after we destroyed the h1s/h2s, that way
later we'll be able to check if the connection has no stream at all, and if
it should be added to the server idling list.
This commit is contained in:
Olivier Houchard 2018-12-15 16:05:40 +01:00 committed by Willy Tarreau
parent b7b3faa79c
commit 8a78690229
2 changed files with 38 additions and 32 deletions

View File

@ -1917,6 +1917,8 @@ static void h1_detach(struct conn_stream *cs)
{
struct h1s *h1s = cs->ctx;
struct h1c *h1c;
int has_keepalive;
int is_not_first;
cs->ctx = NULL;
if (!h1s)
@ -1925,7 +1927,11 @@ static void h1_detach(struct conn_stream *cs)
h1c = h1s->h1c;
h1s->cs = NULL;
if (conn_is_back(h1c->conn) && (h1s->flags & H1S_F_WANT_KAL) &&
has_keepalive = h1s->flags & H1S_F_WANT_KAL;
is_not_first = h1s->flags & H1S_F_NOT_FIRST;
h1s_destroy(h1s);
if (conn_is_back(h1c->conn) && has_keepalive &&
!(h1c->conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) {
struct stream_interface *si = cs->data;
struct stream *s = si_strm(si);
@ -1945,7 +1951,7 @@ static void h1_detach(struct conn_stream *cs)
if (srv) {
if (h1c->conn->flags & CO_FL_PRIVATE)
LIST_ADD(&srv->priv_conns[tid], &h1c->conn->list);
else if (h1s->flags & H1S_F_NOT_FIRST)
else if (is_not_first)
LIST_ADD(&srv->safe_conns[tid], &h1c->conn->list);
else
LIST_ADD(&srv->idle_conns[tid], &h1c->conn->list);
@ -1953,8 +1959,6 @@ static void h1_detach(struct conn_stream *cs)
}
}
h1s_destroy(h1s);
/* We don't want to close right now unless the connection is in error */
if ((h1c->flags & (H1C_F_CS_ERROR|H1C_F_CS_SHUTW)) ||
(h1c->conn->flags & CO_FL_ERROR) || !h1c->conn->owner)

View File

@ -2809,34 +2809,6 @@ static void h2_detach(struct conn_stream *cs)
return;
h2c = h2s->h2c;
if (h2c->proxy->options2 & PR_O2_USE_HTX) {
struct stream_interface *si;
struct stream *s;
si = cs->data;
s = si_strm(si);
if (!(h2c->conn->flags &
(CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) {
if (!h2c->conn->owner) {
h2c->conn->owner = s->sess;
session_add_conn(s->sess, h2c->conn, s->target);
}
/* Never ever allow to reuse a connection from a non-reuse backend */
if ((h2c->proxy->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR)
h2c->conn->flags |= CO_FL_PRIVATE;
if (LIST_ISEMPTY(&h2c->conn->list)) {
struct server *srv = objt_server(h2c->conn->target);
if (srv) {
if (h2c->conn->flags & CO_FL_PRIVATE)
LIST_ADD(&srv->priv_conns[tid], &h2c->conn->list);
else
LIST_ADD(&srv->idle_conns[tid], &h2c->conn->list);
}
}
}
}
h2s->cs = NULL;
h2c->nb_cs--;
if (h2c->flags & H2_CF_DEM_TOOMANY &&
@ -2866,6 +2838,36 @@ static void h2_detach(struct conn_stream *cs)
h2s_destroy(h2s);
if (h2c->flags & H2_CF_IS_BACK &&
(h2c->proxy->options2 & PR_O2_USE_HTX)) {
struct stream_interface *si;
struct stream *s;
si = cs->data;
s = si_strm(si);
if (!(h2c->conn->flags &
(CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) {
if (!h2c->conn->owner) {
h2c->conn->owner = s->sess;
session_add_conn(s->sess, h2c->conn, s->target);
}
/* Never ever allow to reuse a connection from a non-reuse backend */
if ((h2c->proxy->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR)
h2c->conn->flags |= CO_FL_PRIVATE;
if (LIST_ISEMPTY(&h2c->conn->list)) {
struct server *srv = objt_server(h2c->conn->target);
if (srv) {
if (h2c->conn->flags & CO_FL_PRIVATE)
LIST_ADD(&srv->priv_conns[tid], &h2c->conn->list);
else
LIST_ADD(&srv->idle_conns[tid], &h2c->conn->list);
}
}
}
}
/* We don't want to close right now unless we're removing the
* last stream, and either the connection is in error, or it
* reached the ID already specified in a GOAWAY frame received