From: Willy Tarreau Date: Sat, 9 Jul 2022 21:19:19 +0000 (+0200) Subject: MINOR: fd: add fd_reregister_all() to deal with boot-time FDs X-Git-Tag: v2.7-dev2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=88c4c14050451858f1f3cb0169ae900b97e900c4;p=thirdparty%2Fhaproxy.git 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 6319484d6b..d95dcc82b5 100644 --- a/include/haproxy/fd.h +++ b/include/haproxy/fd.h @@ -122,6 +122,7 @@ void fd_add_to_fd_list(volatile struct fdlist *list, int fd); 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 49a3540b68..ca0483f888 100644 --- a/src/fd.c +++ b/src/fd.c @@ -654,6 +654,33 @@ int fd_update_events(int fd, uint evts) 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 parts from followed by parts from * optionally followed by a newline if is non-null, to file descriptor * . The message is sent atomically using writev(). It may be truncated to