MINOR: fd: add fd_reregister_all() to deal with boot-time FDs
At boot the pollers are allocated for each thread and they need to
reprogram updates for all FDs they will manage. This code is not
trivial, especially when trying to respect thread groups, so we'd
rather avoid duplicating it.
Let's centralize this into fd.c with this function. It avoids closed
FDs, those whose thread mask doesn't match the requested one or whose
thread group doesn't match the requested one, and performs the update
if required under thread-group protection.
diff --git a/include/haproxy/fd.h b/include/haproxy/fd.h
index 6319484..d95dcc8 100644
--- a/include/haproxy/fd.h
+++ b/include/haproxy/fd.h
@@ -122,6 +122,7 @@
void fd_rm_from_fd_list(volatile struct fdlist *list, int fd);
void updt_fd_polling(const int fd);
int fd_update_events(int fd, uint evts);
+void fd_reregister_all(int tgrp, ulong mask);
/* Called from the poller to acknowledge we read an entry from the global
* update list, to remove our bit from the update_mask, and remove it from
diff --git a/src/fd.c b/src/fd.c
index 49a3540..ca0483f 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -654,6 +654,33 @@
return FD_UPDT_DONE;
}
+/* This is used by pollers at boot time to re-register desired events for
+ * all FDs after new pollers have been created. It doesn't do much, it checks
+ * that their thread group matches the one in argument, and that the thread
+ * mask matches at least one of the bits in the mask, and if so, marks the FD
+ * as updated.
+ */
+void fd_reregister_all(int tgrp, ulong mask)
+{
+ int fd;
+
+ for (fd = 0; fd < global.maxsock; fd++) {
+ if (!fdtab[fd].owner)
+ continue;
+
+ /* make sure we don't register other tgroups' FDs. We just
+ * avoid needlessly taking the lock if not needed.
+ */
+ if (!(_HA_ATOMIC_LOAD(&fdtab[fd].thread_mask) & mask) ||
+ !fd_grab_tgid(fd, tgrp))
+ continue; // was not for us anyway
+
+ if (_HA_ATOMIC_LOAD(&fdtab[fd].thread_mask) & mask)
+ updt_fd_polling(fd);
+ fd_drop_tgid(fd);
+ }
+}
+
/* Tries to send <npfx> parts from <prefix> followed by <nmsg> parts from <msg>
* optionally followed by a newline if <nl> is non-null, to file descriptor
* <fd>. The message is sent atomically using writev(). It may be truncated to