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.
This commit is contained in:
Willy Tarreau 2022-07-09 23:19:19 +02:00
parent d0b73bca71
commit 88c4c14050
2 changed files with 28 additions and 0 deletions

View File

@ -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

View File

@ -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 <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