BUG/MEDIUM: connection: always update connection flags prior to computing polling

stream_int_chk_rcv_conn() did not clear connection flags before updating them. It
is unsure whether this could have caused the stalled transfers that have been
reported since dev15.

In order to avoid such further issues, we now use a simple inline function to do
all the job.
diff --git a/include/proto/connection.h b/include/proto/connection.h
index ddfb89e..0c07f8c 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -114,6 +114,24 @@
  */
 int conn_local_send_proxy(struct connection *conn, unsigned int flag);
 
+/* Refresh the connection's polling flags from its file descriptor status.
+ * This should be called at the beginning of a connection handler.
+ */
+static inline void conn_refresh_polling_flags(struct connection *conn)
+{
+	conn->flags &= ~(CO_FL_WAIT_ROOM | CO_FL_WAIT_RD | CO_FL_WAIT_DATA | CO_FL_WAIT_WR);
+
+	if (conn->ctrl) {
+		unsigned int flags = conn->flags & ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA);
+
+		if (fd_ev_is_set(conn->t.sock.fd, DIR_RD))
+			flags |= CO_FL_CURR_RD_ENA;
+		if (fd_ev_is_set(conn->t.sock.fd, DIR_WR))
+			flags |= CO_FL_CURR_WR_ENA;
+		conn->flags = flags;
+	}
+}
+
 /* inspects c->flags and returns non-zero if DATA ENA changes from the CURR ENA
  * or if the WAIT flags are set with their respective ENA flags. Additionally,
  * non-zero is also returned if an error was reported on the connection. This
diff --git a/src/connection.c b/src/connection.c
index 519a8f9..f86afde 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -46,18 +46,8 @@
 	if (unlikely(!conn))
 		return 0;
 
-	/* before engaging there, we clear the new WAIT_* flags so that we can
-	 * more easily detect an EAGAIN condition from anywhere.
-	 */
-	flags = conn->flags &= ~(CO_FL_WAIT_DATA|CO_FL_WAIT_ROOM|CO_FL_WAIT_RD|CO_FL_WAIT_WR);
-	flags &= ~CO_FL_ERROR; /* ensure to call the wake handler upon error */
-
-	/* adjust current polling status if it has been updated below us */
-	if (fd_ev_is_set(conn->t.sock.fd, DIR_RD))
-		conn->flags |= CO_FL_CURR_RD_ENA;
-
-	if (fd_ev_is_set(conn->t.sock.fd, DIR_WR))
-		conn->flags |= CO_FL_CURR_WR_ENA;
+	conn_refresh_polling_flags(conn);
+	flags = conn->flags & ~CO_FL_ERROR; /* ensure to call the wake handler upon error */
 
 	if (unlikely(conn->flags & CO_FL_ERROR))
 		goto leave;
diff --git a/src/stream_interface.c b/src/stream_interface.c
index 5f6d85d..bba52e7 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -765,17 +765,20 @@
 	if (unlikely(si->state > SI_ST_EST || (ib->flags & CF_SHUTR)))
 		return;
 
+	conn_refresh_polling_flags(si->conn);
+
 	if ((ib->flags & CF_DONT_READ) || channel_full(ib)) {
 		/* stop reading */
 		if (!(ib->flags & CF_DONT_READ)) /* full */
 			si->flags |= SI_FL_WAIT_ROOM;
-		conn_data_stop_recv(si->conn);
+		__conn_data_stop_recv(si->conn);
 	}
 	else {
 		/* (re)start reading */
 		si->flags &= ~SI_FL_WAIT_ROOM;
-		conn_data_want_recv(si->conn);
+		__conn_data_want_recv(si->conn);
 	}
+	conn_cond_update_data_polling(si->conn);
 }
 
 
@@ -804,9 +807,8 @@
 		 */
 		if (si->conn->ctrl)
 			fd_want_send(si->conn->t.sock.fd);
-		si->conn->flags &= ~(CO_FL_WAIT_DATA|CO_FL_WAIT_ROOM|CO_FL_WAIT_RD|CO_FL_WAIT_WR);
-		if (fd_ev_is_set(si->conn->t.sock.fd, DIR_WR))
-			si->conn->flags |= CO_FL_CURR_WR_ENA;
+
+		conn_refresh_polling_flags(si->conn);
 
 		if (si_conn_send_loop(si->conn) < 0) {
 			/* Write error on the file descriptor */