MINOR: fd: add a bitmask to indicate that an FD is known by the poller

Some pollers like epoll() need to know if the fd is already known or
not in order to compute the operation to perform (add, mod, del). For
now this is performed based on the difference between the previous FD
state and the new state but this will not be usable anymore once threads
become responsible for their own polling.

Here we come with a different approach : a bitmask is stored with the
fd to indicate which pollers already know it, and the pollers will be
able to simply perform the add/mod/del operations based on this bit
combined with the new state.

This patch only adds the bitmask declaration and initialization, it
is it not yet used. It will be needed by the next two fixes and will
need to be backported to 1.8.
diff --git a/include/proto/fd.h b/include/proto/fd.h
index d6b591d..cc559ac 100644
--- a/include/proto/fd.h
+++ b/include/proto/fd.h
@@ -405,6 +405,9 @@
 	fdtab[fd].cloned = 0;
 	fdtab[fd].cache = 0;
 	fdtab[fd].thread_mask = thread_mask;
+	/* note: do not reset polled_mask here as it indicates which poller
+	 * still knows this FD from a possible previous round.
+	 */
 	HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
 
 	HA_SPIN_LOCK(FDTAB_LOCK, &fdtab_lock);
diff --git a/include/types/fd.h b/include/types/fd.h
index 54192e4..9f2c5fe 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -94,6 +94,7 @@
 struct fdtab {
 	__decl_hathreads(HA_SPINLOCK_T lock);
 	unsigned long thread_mask;           /* mask of thread IDs authorized to process the task */
+	unsigned long polled_mask;           /* mask of thread IDs currently polling this fd */
 	unsigned long update_mask;           /* mask of thread IDs having an update for fd */
 	void (*iocb)(int fd);                /* I/O handler */
 	void *owner;                         /* the connection or listener associated with this fd, NULL if closed */
diff --git a/src/fd.c b/src/fd.c
index 112806b..b64130e 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -202,8 +202,10 @@
 	fdtab[fd].update_mask &= ~tid_bit;
 	fdtab[fd].new = 0;
 	fdtab[fd].thread_mask = 0;
-	if (do_close)
+	if (do_close) {
+		fdtab[fd].polled_mask = 0;
 		close(fd);
+	}
 	HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
 
 	HA_SPIN_LOCK(FDTAB_LOCK, &fdtab_lock);