REORG: fd: centralize the processing of speculative events

Speculative events are independant on the poller, so they can be
centralized in fd.c.
diff --git a/src/ev_sepoll.c b/src/ev_sepoll.c
index c5b2a6e..71e4014 100644
--- a/src/ev_sepoll.c
+++ b/src/ev_sepoll.c
@@ -48,7 +48,6 @@
 	int status, eo, en;
 	int fd, opcode;
 	int count;
-	int spec_idx;
 	int updt_idx;
 	int wait_time;
 
@@ -207,42 +206,7 @@
 		}
 	}
 
-	/* now process speculative events if any */
-
-	for (spec_idx = 0; spec_idx < fd_nbspec; ) {
-		fd = fd_spec[spec_idx];
-		eo = fdtab[fd].spec_e;
-
-		/*
-		 * Process the speculative events.
-		 *
-		 * Principle: events which are marked FD_EV_ACTIVE are processed
-		 * with their usual I/O callback. The callback may remove the
-		 * events from the list or tag them for polling. Changes will be
-		 * applied on next round.
-		 */
-
-		fdtab[fd].ev &= FD_POLL_STICKY;
-
-		if ((eo & FD_EV_STATUS_R) == FD_EV_ACTIVE_R)
-			fdtab[fd].ev |= FD_POLL_IN;
-
-		if ((eo & FD_EV_STATUS_W) == FD_EV_ACTIVE_W)
-			fdtab[fd].ev |= FD_POLL_OUT;
-
-		if (fdtab[fd].iocb && fdtab[fd].owner && fdtab[fd].ev)
-			fdtab[fd].iocb(fd);
-
-		/* if the fd was removed from the spec list, it has been
-		 * replaced by the next one that we don't want to skip !
-		 */
-		if (spec_idx < fd_nbspec && fd_spec[spec_idx] != fd)
-			continue;
-
-		spec_idx++;
-	}
-
-	/* in the end, we have processed status + spec_processed FDs */
+	/* the caller will take care of speculative events */
 }
 
 /*
diff --git a/src/fd.c b/src/fd.c
index 2718748..ac6ec5f 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -132,6 +132,48 @@
 		maxfd--;
 }
 
+/* Scan and process the speculative events. This should be called right after
+ * the poller.
+ */
+void fd_process_spec_events()
+{
+	int fd, spec_idx, e;
+
+	/* now process speculative events if any */
+
+	for (spec_idx = 0; spec_idx < fd_nbspec; ) {
+		fd = fd_spec[spec_idx];
+		e = fdtab[fd].spec_e;
+
+		/*
+		 * Process the speculative events.
+		 *
+		 * Principle: events which are marked FD_EV_ACTIVE are processed
+		 * with their usual I/O callback. The callback may remove the
+		 * events from the list or tag them for polling. Changes will be
+		 * applied on next round.
+		 */
+
+		fdtab[fd].ev &= FD_POLL_STICKY;
+
+		if ((e & FD_EV_STATUS_R) == FD_EV_ACTIVE_R)
+			fdtab[fd].ev |= FD_POLL_IN;
+
+		if ((e & FD_EV_STATUS_W) == FD_EV_ACTIVE_W)
+			fdtab[fd].ev |= FD_POLL_OUT;
+
+		if (fdtab[fd].iocb && fdtab[fd].owner && fdtab[fd].ev)
+			fdtab[fd].iocb(fd);
+
+		/* if the fd was removed from the spec list, it has been
+		 * replaced by the next one that we don't want to skip !
+		 */
+		if (spec_idx < fd_nbspec && fd_spec[spec_idx] != fd)
+			continue;
+
+		spec_idx++;
+	}
+}
 
 /* disable the specified poller */
 void disable_poller(const char *poller_name)
diff --git a/src/haproxy.c b/src/haproxy.c
index d973ae2..1bb65c1 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1216,6 +1216,7 @@
 
 		/* The poller will ensure it returns around <next> */
 		cur_poller.poll(&cur_poller, next);
+		fd_process_spec_events();
 	}
 }