BUG/MEDIUM: connection: always disable polling upon error

Commit 0ffde2cc in 1.5-dev13 tried to always disable polling on file
descriptors when errors were encountered. Unfortunately it did not
always succeed in doing so because it relied on detecting polling
changes to disable it. Let's use a dedicated conn_stop_polling()
function that is inconditionally called upon error instead.

This managed to stop a busy loop observed when a health check makes
use of the send-proxy protocol and fails before the connection can
be established.
diff --git a/include/proto/connection.h b/include/proto/connection.h
index 3bf337d..35b6312 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -180,6 +180,17 @@
 		conn_update_sock_polling(c);
 }
 
+/* Stop all polling on the fd. This might be used when an error is encountered
+ * for example.
+ */
+static inline void conn_stop_polling(struct connection *c)
+{
+	c->flags &= ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA |
+		      CO_FL_SOCK_RD_ENA | CO_FL_SOCK_WR_ENA |
+		      CO_FL_DATA_RD_ENA | CO_FL_DATA_WR_ENA);
+	fd_stop_both(c->t.sock.fd);
+}
+
 /* Automatically update polling on connection <c> depending on the DATA and
  * SOCK flags, and on whether a handshake is in progress or not. This may be
  * called at any moment when there is a doubt about the effectiveness of the
@@ -187,7 +198,9 @@
  */
 static inline void conn_cond_update_polling(struct connection *c)
 {
-	if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
+	if (unlikely(c->flags & CO_FL_ERROR))
+		conn_stop_polling(c);
+	else if (!(c->flags & CO_FL_POLL_SOCK) && conn_data_polling_changes(c))
 		conn_update_data_polling(c);
 	else if ((c->flags & CO_FL_POLL_SOCK) && conn_sock_polling_changes(c))
 		conn_update_sock_polling(c);
diff --git a/src/connection.c b/src/connection.c
index 8038a74..9549dba 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -166,14 +166,6 @@
 {
 	unsigned int f = c->flags;
 
-	if (unlikely(f & CO_FL_ERROR)) {
-		c->flags &= ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA |
-		              CO_FL_SOCK_RD_ENA | CO_FL_SOCK_WR_ENA |
-		              CO_FL_DATA_RD_ENA | CO_FL_DATA_WR_ENA);
-		fd_stop_both(c->t.sock.fd);
-		return;
-	}
-
 	/* update read status if needed */
 	if (unlikely((f & (CO_FL_DATA_RD_ENA|CO_FL_WAIT_RD)) == (CO_FL_DATA_RD_ENA|CO_FL_WAIT_RD))) {
 		fd_poll_recv(c->t.sock.fd);
@@ -214,14 +206,6 @@
 {
 	unsigned int f = c->flags;
 
-	if (unlikely(f & CO_FL_ERROR)) {
-		c->flags &= ~(CO_FL_CURR_RD_ENA | CO_FL_CURR_WR_ENA |
-		              CO_FL_SOCK_RD_ENA | CO_FL_SOCK_WR_ENA |
-		              CO_FL_DATA_RD_ENA | CO_FL_DATA_WR_ENA);
-		fd_stop_both(c->t.sock.fd);
-		return;
-	}
-
 	/* update read status if needed */
 	if (unlikely((f & (CO_FL_SOCK_RD_ENA|CO_FL_WAIT_RD)) == (CO_FL_SOCK_RD_ENA|CO_FL_WAIT_RD))) {
 		fd_poll_recv(c->t.sock.fd);