From: Willy Tarreau Date: Fri, 9 Nov 2012 17:27:26 +0000 (+0100) Subject: OPTIM: stream_interface: disable reading when CF_READ_DONTWAIT is set X-Git-Tag: v1.5-dev13~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5fddab0;p=thirdparty%2Fhaproxy.git OPTIM: stream_interface: disable reading when CF_READ_DONTWAIT is set CF_READ_DONTWAIT was designed to avoid getting an EAGAIN upon recv() when very few data are expected. It prevents the reader from looping over recv(). Unfortunately with speculative I/O, it is very common that the same event has the time to be called twice before the task handles the data and disables the recv(). This is because not all tasks are always processed at once. Instead of leaving the buffer free-wheeling and doing an EAGAIN, we disable reading as soon as the first recv() succeeds. This way we're sure that only the next wakeup of the task will re-enable it if needed. Doing so has totally removed the EAGAIN we were seeing till now (30% of recv). --- diff --git a/src/stream_interface.c b/src/stream_interface.c index deb14b4cf8..5a7bbc6f13 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -1086,8 +1086,10 @@ static void si_conn_recv_cb(struct connection *conn) break; } - if ((chn->flags & CF_READ_DONTWAIT) || --read_poll <= 0) + if ((chn->flags & CF_READ_DONTWAIT) || --read_poll <= 0) { + conn_data_stop_recv(conn); break; + } /* if too many bytes were missing from last read, it means that * it's pointless trying to read again because the system does