MEDIUM: protocols: use the generic I/O callback for accept callbacks

This one is used only on read events, and it was easy to convert to
use the new I/O callback.
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 41a31b8..5c04fb4 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -821,9 +821,9 @@
 
 	fdtab[fd].owner = listener; /* reference the listener instead of a task */
 	fdtab[fd].flags = FD_FL_TCP | ((listener->options & LI_O_NOLINGER) ? FD_FL_TCP_NOLING : 0);
-	fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
+	fdtab[fd].iocb = listener->proto->accept;
+	fdtab[fd].cb[DIR_RD].f = NULL; /* never called */
 	fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
-	fdtab[fd].iocb = NULL;
 	fd_insert(fd);
 
  tcp_return:
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 2dc5613..b1484b6 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -262,9 +262,9 @@
 
 	/* the function for the accept() event */
 	fd_insert(fd);
-	fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
+	fdtab[fd].iocb = listener->proto->accept;
+	fdtab[fd].cb[DIR_RD].f = NULL; /* never called */
 	fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
-	fdtab[fd].iocb = NULL;
 	fdtab[fd].owner = listener; /* reference the listener instead of a task */
 	return ERR_NONE;
  err_rename:
diff --git a/src/protocols.c b/src/protocols.c
index adbe44d..b31664b 100644
--- a/src/protocols.c
+++ b/src/protocols.c
@@ -240,6 +240,7 @@
 /* This function is called on a read event from a listening socket, corresponding
  * to an accept. It tries to accept as many connections as possible, and for each
  * calls the listener's accept handler (generally the frontend's accept handler).
+ * It returns FD_WAIT_READ or zero.
  */
 int listener_accept(int fd)
 {
@@ -251,7 +252,7 @@
 
 	if (unlikely(l->nbconn >= l->maxconn)) {
 		listener_full(l);
-		return 0;
+		return FD_WAIT_READ;
 	}
 
 	if (global.cps_lim && !(l->options & LI_O_UNLIMITED)) {
@@ -261,7 +262,7 @@
 			/* frontend accept rate limit was reached */
 			limit_listener(l, &global_listener_queue);
 			task_schedule(global_listener_queue_task, tick_add(now_ms, next_event_delay(&global.conn_per_sec, global.cps_lim, 0)));
-			return 0;
+			return FD_WAIT_READ;
 		}
 
 		if (max_accept > max)
@@ -275,7 +276,7 @@
 			/* frontend accept rate limit was reached */
 			limit_listener(l, &p->listener_queue);
 			task_schedule(p->task, tick_add(now_ms, next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 0)));
-			return 0;
+			return FD_WAIT_READ;
 		}
 
 		if (max_accept > max)
@@ -294,12 +295,12 @@
 		if (unlikely(actconn >= global.maxconn) && !(l->options & LI_O_UNLIMITED)) {
 			limit_listener(l, &global_listener_queue);
 			task_schedule(global_listener_queue_task, tick_add(now_ms, 1000)); /* try again in 1 second */
-			return 0;
+			return FD_WAIT_READ;
 		}
 
 		if (unlikely(p && p->feconn >= p->maxconn)) {
 			limit_listener(l, &p->listener_queue);
-			return 0;
+			return FD_WAIT_READ;
 		}
 
 		cfd = accept(fd, (struct sockaddr *)&addr, &laddr);
@@ -308,7 +309,7 @@
 			case EAGAIN:
 			case EINTR:
 			case ECONNABORTED:
-				return 0;	    /* nothing more to accept */
+				return FD_WAIT_READ;   /* nothing more to accept */
 			case ENFILE:
 				if (p)
 					send_log(p, LOG_EMERG,
@@ -316,7 +317,7 @@
 						 p->id, maxfd);
 				limit_listener(l, &global_listener_queue);
 				task_schedule(global_listener_queue_task, tick_add(now_ms, 100)); /* try again in 100 ms */
-				return 0;
+				return FD_WAIT_READ;
 			case EMFILE:
 				if (p)
 					send_log(p, LOG_EMERG,
@@ -324,7 +325,7 @@
 						 p->id, maxfd);
 				limit_listener(l, &global_listener_queue);
 				task_schedule(global_listener_queue_task, tick_add(now_ms, 100)); /* try again in 100 ms */
-				return 0;
+				return FD_WAIT_READ;
 			case ENOBUFS:
 			case ENOMEM:
 				if (p)
@@ -333,9 +334,9 @@
 						 p->id, maxfd);
 				limit_listener(l, &global_listener_queue);
 				task_schedule(global_listener_queue_task, tick_add(now_ms, 100)); /* try again in 100 ms */
-				return 0;
+				return FD_WAIT_READ;
 			default:
-				return 0;
+				return FD_WAIT_READ;
 			}
 		}
 
@@ -358,7 +359,7 @@
 			close(cfd);
 			limit_listener(l, &global_listener_queue);
 			task_schedule(global_listener_queue_task, tick_add(now_ms, 1000)); /* try again in 1 second */
-			return 0;
+			return FD_WAIT_READ;
 		}
 
 		/* increase the per-process number of cumulated connections */
@@ -394,16 +395,17 @@
 
 			limit_listener(l, &global_listener_queue);
 			task_schedule(global_listener_queue_task, tick_add(now_ms, 100)); /* try again in 100 ms */
-			return 0;
+			return FD_WAIT_READ;
 		}
 
 		if (l->nbconn >= l->maxconn) {
 			listener_full(l);
-			return 0;
+			return FD_WAIT_READ;
 		}
 
-	} /* end of while (p->feconn < p->maxconn) */
+	} /* end of while (max_accept--) */
 
+	/* we've exhausted max_accept, so there is no need to poll again */
 	return 0;
 }