MAJOR: connection: remove the CO_FL_WAIT_{RD,WR} flags

These flags were used to report the readiness of the file descriptor.
Now this readiness is directly checked at the file descriptor itself.
This removes the need for constantly synchronizing updates between the
file descriptor and the connection and ensures that all layers share
the same level of information.

For now, the readiness is updated in conn_{sock,data}_poll_* by directly
touching the file descriptor. This must move to the lower layers instead
so that these functions can disappear as well. In this state, the change
works but is incomplete. It's sensible enough to avoid making it more
complex.

Now the sock/data updates become much simpler because they just have to
enable/disable access to a file descriptor and not to care anymore about
its readiness.
diff --git a/src/checks.c b/src/checks.c
index bdc7a6b..82aec1a 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -934,7 +934,7 @@
 	if (unlikely(check->result == CHK_RES_FAILED))
 		goto out_wakeup;
 
-	if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_WR))
+	if (conn->flags & CO_FL_HANDSHAKE)
 		return;
 
 	if (retrieve_errno_from_socket(conn)) {
@@ -1011,7 +1011,7 @@
 	if (unlikely(check->result == CHK_RES_FAILED))
 		goto out_wakeup;
 
-	if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_RD))
+	if (conn->flags & CO_FL_HANDSHAKE)
 		return;
 
 	if (check->type == PR_O2_TCPCHK_CHK) {
@@ -2006,8 +2006,7 @@
 		     check->current_step->action != TCPCHK_ACT_SEND ||
 		     check->current_step->string_len >= buffer_total_space(check->bo))) {
 
-			if ((conn->flags & CO_FL_WAIT_WR) ||
-			    conn->xprt->snd_buf(conn, check->bo, MSG_DONTWAIT | MSG_NOSIGNAL) <= 0) {
+			if (conn->xprt->snd_buf(conn, check->bo, MSG_DONTWAIT | MSG_NOSIGNAL) <= 0) {
 				if (conn->flags & CO_FL_ERROR) {
 					chk_report_conn_err(conn, errno, 0);
 					__conn_data_stop_both(conn);
@@ -2060,8 +2059,7 @@
 			if (unlikely(check->result == CHK_RES_FAILED))
 				goto out_end_tcpcheck;
 
-			if ((conn->flags & CO_FL_WAIT_RD) ||
-			    conn->xprt->rcv_buf(conn, check->bi, check->bi->size) <= 0) {
+			if (conn->xprt->rcv_buf(conn, check->bi, check->bi->size) <= 0) {
 				if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH)) {
 					done = 1;
 					if ((conn->flags & CO_FL_ERROR) && !check->bi->i) {
diff --git a/src/connection.c b/src/connection.c
index 367d1e3..0056ec0 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -59,7 +59,7 @@
 	 * around.
 	 */
 	while (unlikely(conn->flags & (CO_FL_HANDSHAKE | CO_FL_ERROR))) {
-		if (unlikely(conn->flags & (CO_FL_ERROR|CO_FL_WAIT_RD|CO_FL_WAIT_WR)))
+		if (unlikely(conn->flags & CO_FL_ERROR))
 			goto leave;
 
 		if (conn->flags & CO_FL_ACCEPT_PROXY)
@@ -94,7 +94,8 @@
 	 */
 	if ((fdtab[fd].ev & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR)) &&
 	    conn->xprt &&
-	    !(conn->flags & (CO_FL_WAIT_RD|CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE))) {
+	    fd_recv_ready(fd) &&
+	    !(conn->flags & (CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE))) {
 		/* force detection of a flag change : it's impossible to have both
 		 * CONNECTED and WAIT_CONN so we're certain to trigger a change.
 		 */
@@ -104,7 +105,8 @@
 
 	if ((fdtab[fd].ev & (FD_POLL_OUT | FD_POLL_ERR)) &&
 	    conn->xprt &&
-	    !(conn->flags & (CO_FL_WAIT_WR|CO_FL_WAIT_DATA|CO_FL_ERROR|CO_FL_HANDSHAKE))) {
+	    fd_send_ready(fd) &&
+	    !(conn->flags & (CO_FL_WAIT_DATA|CO_FL_ERROR|CO_FL_HANDSHAKE))) {
 		/* force detection of a flag change : it's impossible to have both
 		 * CONNECTED and WAIT_CONN so we're certain to trigger a change.
 		 */
@@ -118,7 +120,7 @@
 	if (unlikely(conn->flags & (CO_FL_HANDSHAKE | CO_FL_ERROR)))
 		goto process_handshake;
 
-	if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && !(conn->flags & CO_FL_WAIT_WR)) {
+	if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && fd_send_ready(conn->t.sock.fd)) {
 		/* still waiting for a connection to establish and nothing was
 		 * attempted yet to probe the connection. Then let's retry the
 		 * connect().
@@ -163,27 +165,17 @@
 		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))) {
+	if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_DATA_RD_ENA)) == CO_FL_DATA_RD_ENA)) {
 		fd_want_recv(c->t.sock.fd);
-		fd_cant_recv(c->t.sock.fd);
 		f |= CO_FL_CURR_RD_ENA;
 	}
-	else if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_DATA_RD_ENA)) == CO_FL_DATA_RD_ENA)) {
-		fd_want_recv(c->t.sock.fd);
-		f |= CO_FL_CURR_RD_ENA;
-	}
 	else if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_DATA_RD_ENA)) == CO_FL_CURR_RD_ENA)) {
 		fd_stop_recv(c->t.sock.fd);
 		f &= ~CO_FL_CURR_RD_ENA;
 	}
 
 	/* update write status if needed */
-	if (unlikely((f & (CO_FL_DATA_WR_ENA|CO_FL_WAIT_WR)) == (CO_FL_DATA_WR_ENA|CO_FL_WAIT_WR))) {
-		fd_want_send(c->t.sock.fd);
-		fd_cant_send(c->t.sock.fd);
-		f |= CO_FL_CURR_WR_ENA;
-	}
-	else if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_DATA_WR_ENA)) == CO_FL_DATA_WR_ENA)) {
+	if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_DATA_WR_ENA)) == CO_FL_DATA_WR_ENA)) {
 		fd_want_send(c->t.sock.fd);
 		f |= CO_FL_CURR_WR_ENA;
 	}
@@ -191,7 +183,7 @@
 		fd_stop_send(c->t.sock.fd);
 		f &= ~CO_FL_CURR_WR_ENA;
 	}
-	c->flags = f & ~(CO_FL_WAIT_RD | CO_FL_WAIT_WR);
+	c->flags = f;
 }
 
 /* Update polling on connection <c>'s file descriptor depending on its current
@@ -208,35 +200,25 @@
 		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))) {
+	if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_SOCK_RD_ENA)) == CO_FL_SOCK_RD_ENA)) {
 		fd_want_recv(c->t.sock.fd);
-		fd_cant_recv(c->t.sock.fd);
 		f |= CO_FL_CURR_RD_ENA;
 	}
-	else if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_SOCK_RD_ENA)) == CO_FL_SOCK_RD_ENA)) {
-		fd_want_recv(c->t.sock.fd);
-		f |= CO_FL_CURR_RD_ENA;
-	}
 	else if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_SOCK_RD_ENA)) == CO_FL_CURR_RD_ENA)) {
 		fd_stop_recv(c->t.sock.fd);
 		f &= ~CO_FL_CURR_RD_ENA;
 	}
 
 	/* update write status if needed */
-	if (unlikely((f & (CO_FL_SOCK_WR_ENA|CO_FL_WAIT_WR)) == (CO_FL_SOCK_WR_ENA|CO_FL_WAIT_WR))) {
+	if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_SOCK_WR_ENA)) == CO_FL_SOCK_WR_ENA)) {
 		fd_want_send(c->t.sock.fd);
-		fd_cant_send(c->t.sock.fd);
 		f |= CO_FL_CURR_WR_ENA;
 	}
-	else if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_SOCK_WR_ENA)) == CO_FL_SOCK_WR_ENA)) {
-		fd_want_send(c->t.sock.fd);
-		f |= CO_FL_CURR_WR_ENA;
-	}
 	else if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_SOCK_WR_ENA)) == CO_FL_CURR_WR_ENA)) {
 		fd_stop_send(c->t.sock.fd);
 		f &= ~CO_FL_CURR_WR_ENA;
 	}
-	c->flags = f & ~(CO_FL_WAIT_RD | CO_FL_WAIT_WR);
+	c->flags = f;
 }
 
 /* This handshake handler waits a PROXY protocol header at the beginning of the
diff --git a/src/stream_interface.c b/src/stream_interface.c
index 6d15edc..063c173 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -679,7 +679,7 @@
 	/* when we're here, we already know that there is no spliced
 	 * data left, and that there are sendable buffered data.
 	 */
-	if (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_DATA_WR_SH | CO_FL_WAIT_DATA | CO_FL_WAIT_WR | CO_FL_HANDSHAKE))) {
+	if (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_DATA_WR_SH | CO_FL_WAIT_DATA | CO_FL_HANDSHAKE))) {
 		/* check if we want to inform the kernel that we're interested in
 		 * sending more data after this call. We want this if :
 		 *  - we're about to close after this last send and want to merge
@@ -1158,7 +1158,7 @@
 	 * that if such an event is not handled above in splice, it will be handled here by
 	 * recv().
 	 */
-	while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH | CO_FL_WAIT_RD | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE))) {
+	while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE))) {
 		max = bi_avail(chn);
 
 		if (!max) {