summaryrefslogtreecommitdiffstats
path: root/src/stream.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:20:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:20:30 +0000
commitddfc40eabdbc59a607b568e946fb116dcd3439fd (patch)
treeb3253de65399448dbbf12e5b65d2da56c53d3af6 /src/stream.c
parentAdding upstream version 2.9.6. (diff)
downloadhaproxy-ddfc40eabdbc59a607b568e946fb116dcd3439fd.tar.xz
haproxy-ddfc40eabdbc59a607b568e946fb116dcd3439fd.zip
Adding upstream version 2.9.7.upstream/2.9.7
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/stream.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/stream.c b/src/stream.c
index a3c0c93..e643a6d 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -537,7 +537,7 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer
s->res.analyse_exp = TICK_ETERNITY;
s->txn = NULL;
- s->hlua = NULL;
+ s->hlua[0] = s->hlua[1] = NULL;
s->resolv_ctx.requester = NULL;
s->resolv_ctx.hostname_dn = NULL;
@@ -649,8 +649,10 @@ void stream_free(struct stream *s)
flt_stream_stop(s);
flt_stream_release(s, 0);
- hlua_ctx_destroy(s->hlua);
- s->hlua = NULL;
+ hlua_ctx_destroy(s->hlua[0]);
+ hlua_ctx_destroy(s->hlua[1]);
+ s->hlua[0] = s->hlua[1] = NULL;
+
if (s->txn)
http_destroy_txn(s);
@@ -2367,7 +2369,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
/* shutdown(write) pending */
if (unlikely((scb->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) == SC_FL_SHUT_WANTED &&
- (!co_data(req) || (req->flags & CF_WRITE_TIMEOUT)))) {
+ ((!co_data(req) && !sc_ep_have_ff_data(scb)) || (req->flags & CF_WRITE_TIMEOUT)))) {
if (scf->flags & SC_FL_ERROR)
scb->flags |= SC_FL_NOLINGER;
sc_shutdown(scb);
@@ -2475,7 +2477,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
/* shutdown(write) pending */
if (unlikely((scf->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) == SC_FL_SHUT_WANTED &&
- (!co_data(res) || (res->flags & CF_WRITE_TIMEOUT)))) {
+ ((!co_data(res) && !sc_ep_have_ff_data(scf)) || (res->flags & CF_WRITE_TIMEOUT)))) {
sc_shutdown(scf);
}
@@ -2681,6 +2683,20 @@ void sess_change_server(struct stream *strm, struct server *newsrv)
{
struct server *oldsrv = strm->srv_conn;
+ /* Dynamic servers may be deleted during process lifetime. This
+ * operation is always conducted under thread isolation. Several
+ * conditions prevent deletion, one of them is if server streams list
+ * is not empty. sess_change_server() uses stream_add_srv_conn() to
+ * ensure the latter condition.
+ *
+ * A race condition could exist for stream which referenced a server
+ * instance (s->target) without registering itself in its server list.
+ * This is notably the case for SF_DIRECT streams which referenced a
+ * server earlier during process_stream(). However at this time the
+ * code is deemed safe as process_stream() cannot be rescheduled before
+ * invocation of sess_change_server().
+ */
+
if (oldsrv == newsrv)
return;