diff --git a/include/proto/connection.h b/include/proto/connection.h index fce602599..6a24dec1e 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -296,6 +296,20 @@ static inline void __conn_data_stop_recv(struct connection *c) c->flags &= ~CO_FL_DATA_RD_ENA; } +/* this one is used only to stop speculative recv(). It doesn't stop it if the + * fd is already polled in order to avoid expensive polling status changes. + * Since it might require the upper layer to re-enable reading, we'll return 1 + * if we've really stopped something otherwise zero. + */ +static inline int __conn_data_done_recv(struct connection *c) +{ + if (!conn_ctrl_ready(c) || !fd_recv_polled(c->t.sock.fd)) { + c->flags &= ~CO_FL_DATA_RD_ENA; + return 1; + } + return 0; +} + static inline void __conn_data_want_send(struct connection *c) { c->flags |= CO_FL_DATA_WR_ENA; diff --git a/src/stream_interface.c b/src/stream_interface.c index 4f93a2e2a..e3e6cc66b 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -1173,8 +1173,8 @@ static void si_conn_recv_cb(struct connection *conn) } if ((ic->flags & CF_READ_DONTWAIT) || --read_poll <= 0) { - si->flags |= SI_FL_WAIT_ROOM; - __conn_data_stop_recv(conn); + if (__conn_data_done_recv(conn)) + si->flags |= SI_FL_WAIT_ROOM; break; }