Hi, On Wed, Nov 25, 2015 at 09:31:45PM +0800, baiyang wrote: > Hi > > Ok, I'll try to disable this option anyway to dig up more clues of this > issue.
Could you please try the appended patch, or simply disable the client-fin and server-fin timeouts ? What I've seen in the code is stupid and can produce the output you sent me. Basically we enable a write-timeout on the other side when we face a read shutdown. This is stupid because we might very well have already disabled the write timeout because we already closed or we don't have anything to send. In the trace you sent me, we have exactly this case with timeouts enabled on closed sides, which explains why they are ignored. I'd like to make this part more robust in the future but for now we must stop the root cause. Thanks, Willy
diff --git a/src/stream.c b/src/stream.c index 1310896..85f00c8 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2091,10 +2091,12 @@ struct task *process_stream(struct task *t) if (unlikely((req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) == (CF_AUTO_CLOSE|CF_SHUTR))) { channel_shutw_now(req); - if (tick_isset(sess->fe->timeout.clientfin)) { - res->wto = sess->fe->timeout.clientfin; - res->wex = tick_add(now_ms, res->wto); - } + // This is wrong, we must not change the outgoing timeout, it may already + // be stopped. + //if (tick_isset(sess->fe->timeout.clientfin)) { + // res->wto = sess->fe->timeout.clientfin; + // res->wex = tick_add(now_ms, res->wto); + //} } /* shutdown(write) pending */ @@ -2119,10 +2121,12 @@ struct task *process_stream(struct task *t) if (si_f->flags & SI_FL_NOHALF) si_f->flags |= SI_FL_NOLINGER; si_shutr(si_f); - if (tick_isset(sess->fe->timeout.clientfin)) { - res->wto = sess->fe->timeout.clientfin; - res->wex = tick_add(now_ms, res->wto); - } + // This is wrong, we must not change the outgoing timeout, it may already + // be stopped. + //if (tick_isset(sess->fe->timeout.clientfin)) { + // res->wto = sess->fe->timeout.clientfin; + // res->wex = tick_add(now_ms, res->wto); + //} } /* it's possible that an upper layer has requested a connection setup or abort. @@ -2284,10 +2288,12 @@ struct task *process_stream(struct task *t) if (unlikely((res->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) == (CF_AUTO_CLOSE|CF_SHUTR))) { channel_shutw_now(res); - if (tick_isset(s->be->timeout.serverfin)) { - req->wto = s->be->timeout.serverfin; - req->wex = tick_add(now_ms, req->wto); - } + // This is wrong, we must not change the outgoing timeout, it may already + // be stopped. + //if (tick_isset(s->be->timeout.serverfin)) { + // req->wto = s->be->timeout.serverfin; + // req->wex = tick_add(now_ms, req->wto); + //} } /* shutdown(write) pending */ @@ -2310,10 +2316,12 @@ struct task *process_stream(struct task *t) if (si_b->flags & SI_FL_NOHALF) si_b->flags |= SI_FL_NOLINGER; si_shutr(si_b); - if (tick_isset(s->be->timeout.serverfin)) { - req->wto = s->be->timeout.serverfin; - req->wex = tick_add(now_ms, req->wto); - } + // This is wrong, we must not change the outgoing timeout, it may already + // be stopped. + //if (tick_isset(s->be->timeout.serverfin)) { + // req->wto = s->be->timeout.serverfin; + // req->wex = tick_add(now_ms, req->wto); + //} } if (si_f->state == SI_ST_DIS || si_b->state == SI_ST_DIS)