Hi Cyril,
just reproduced and found it !
It was not an easy one this time. The issue clearly was because of
the shutdown(write) just after the send() in socat. But while the
stats code was correct, there was something in the session handling
code aborting the establishment of a connection to a stream interface
in such a case, and only if there was no analyser (eg: unix_stream
or pure TCP). The reason for it to appear more easily with concurrency
was because stats tasks are niced and less of them are processed in
the same loop, which leaves more time for the second task to gather
a full request and the shutdown.
Here's the patch I'm going to merge. I did a bunch of tests on it (both unix and tcp) and it appears OK.
Cheers,
Willy
The BF_AUTO_CLOSE flag prevented a connection from establishing on a server if the other side's input channel was already closed. This is wrong because there may be pending data to be sent.
This was causing an issue with stats, as noticed and reported by Cyril Bonté. Since the stats are now handled as a server, sometimes concurrent accesses were causing one of the connections to send the shutdown(write) before the connection to the stats function was established, which aborted it early.
This fix causes the BF_AUTO_CLOSE flag to be checked only when the connection on the outgoing stream interface has reached an established state. That way we're still able to connect, send the request then close.
--- src/session.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/session.c b/src/session.c index 515a275..aa79457 100644 --- a/src/session.c +++ b/src/session.c @@ -1331,10 +1331,12 @@ resync_stream_interface:Received on 2010/03/14 19:58
/* first, let's check if the request buffer needs to shutdown(write), which may
* happen either because the input is closed or because we want to force a close - * once the server has begun to respond. + * once the server has begun to respond. Note that we only apply it once we're + * connected, so that we still support queuing of a request with input already + * closed. */ if (unlikely((s->req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK|BF_AUTO_CLOSE|BF_SHUTR)) == - (BF_AUTO_CLOSE|BF_SHUTR))) + (BF_AUTO_CLOSE|BF_SHUTR) && s->req->cons->state >= SI_ST_EST)) buffer_shutw_now(s->req);
/* shutdown(write) pending */
-- 1.6.4.4
This archive was generated by hypermail 2.2.0 : 2010/03/14 20:00 CET