diff --git a/src/stconn.c b/src/stconn.c index 0383e2404..acfa6cc39 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -531,7 +531,7 @@ static inline int sc_cond_forward_shut(struct stconn *sc) if (!(sc->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) || !(sc->flags & SC_FL_NOHALF)) return 0; - if (co_data(sc_ic(sc)) && !(sc_ic(sc)->flags & CF_WRITE_TIMEOUT)) { + if ((co_data(sc_ic(sc)) || sc_ep_have_ff_data(sc_opposite(sc))) && !(sc_ic(sc)->flags & CF_WRITE_TIMEOUT)) { /* the shutdown cannot be forwarded now because * we should flush outgoing data first. But instruct the output * channel it should be done ASAP. @@ -1067,7 +1067,7 @@ void sc_notify(struct stconn *sc) struct task *task = sc_strm_task(sc); /* process consumer side */ - if (!co_data(oc)) { + if (!co_data(oc) && !sc_ep_have_ff_data(sco)) { struct connection *conn = sc_conn(sc); if (((sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) == SC_FL_SHUT_WANTED) && diff --git a/src/stream.c b/src/stream.c index 9d99d2f6b..7052f7c30 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2369,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); @@ -2477,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); }