From: Willy Tarreau Date: Mon, 27 Feb 2023 17:35:39 +0000 (+0100) Subject: BUG/MINOR: fd: used the update list from the fd's group instead of tgid X-Git-Tag: v2.8-dev5~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0f6f5755bb0b15ffc614f36e6bc704bcf39b68f;p=thirdparty%2Fhaproxy.git BUG/MINOR: fd: used the update list from the fd's group instead of tgid In _fd_delete_orphan() we try to remove the FD from its update list which is supposed to be the current thread group's. However the function might be called from another group during stopping or under isolation, so FD is not queued in the current group's update list but in its own group's list. Let's retrieve the group from the FD instead of using tgid. This should have no impact on existing code since there is no code path calling fd_delete() under thread isolation for now, and other cases are blocked in fd_delete(). This must be backported to 2.7. --- diff --git a/src/fd.c b/src/fd.c index aaf0e38b24..89fdfb3c65 100644 --- a/src/fd.c +++ b/src/fd.c @@ -296,11 +296,13 @@ done: /* deletes the FD once nobody uses it anymore, as detected by the caller by its * thread_mask being zero and its running mask turning to zero. There is no * protection against concurrent accesses, it's up to the caller to make sure - * only the last thread will call it. This is only for internal use, please use - * fd_delete() instead. + * only the last thread will call it. If called under isolation, it is safe to + * call this from another group than the FD's. This is only for internal use, + * please use fd_delete() instead. */ void _fd_delete_orphan(int fd) { + int tgrp = fd_tgid(fd); uint fd_disown; fd_disown = fdtab[fd].state & FD_DISOWN; @@ -318,7 +320,7 @@ void _fd_delete_orphan(int fd) cur_poller.clo(fd); /* we don't want this FD anymore in the global list */ - fd_rm_from_fd_list(&update_list[tgid - 1], fd); + fd_rm_from_fd_list(&update_list[tgrp - 1], fd); /* no more updates on this FD are relevant anymore */ HA_ATOMIC_STORE(&fdtab[fd].update_mask, 0);