MINOR: fd: add a new FD_DISOWN flag to prevent from closing a deleted FD
Some FDs might be offered to some external code (external libraries)
which will deal with them until they close them. As such we must not
close them upon fd_delete() but we need to delete them anyway so that
they do not appear anymore in the fdtab. This used to be handled by
fd_remove() before 2.3 but we don't have this anymore.
This patch introduces a new flag FD_DISOWN to let fd_delete() know that
the core doesn't own the fd and it must not be closed upon removal from
the fd_tab. This way it's totally unregistered from the poller but still
open.
This patch must be backported on branches >= 2.3 because it will be
needed to fix a bug affecting SSL async. it should be adapted on 2.3
because state flags were stored in a different way (via bits in the
structure).
(cherry picked from commit f41a3f6762ce3ccc79f016a052ac03863de7d49d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 7e47164fe3b327a2a281db85e36b442a8c4266c8)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6ac570c6f2ff3d6ff4711ca49d824c25c47f7339)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/fd.c b/src/fd.c
index fe712a9..b9c8ccc 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -304,6 +304,9 @@
*/
void _fd_delete_orphan(int fd)
{
+ uint fd_disown;
+
+ fd_disown = fdtab[fd].state & FD_DISOWN;
if (fdtab[fd].state & FD_LINGER_RISK) {
/* this is generally set when connecting to servers */
DISGUISE(setsockopt(fd, SOL_SOCKET, SO_LINGER,
@@ -325,7 +328,8 @@
/* perform the close() call last as it's what unlocks the instant reuse
* of this FD by any other thread.
*/
- close(fd);
+ if (!fd_disown)
+ close(fd);
_HA_ATOMIC_DEC(&ha_used_fds);
}