srv_close_idle_conns() runs at deinit, on the last remaining thread,
and closes the FDs of every thread's idle connections. With
per-thread-group FD tables, the connections of the other thread groups
were already closed by the kernel when the last thread of their group
exited, and their numbers are only meaningful in those groups' tables,
closing them from here would in fact close whatever FD carries the
same number in this thread's own table, and let sock_conn_ctrl_close()
rewrite an unrelated entry of this group's FD table. So in that case,
only release the memory and leave the FDs alone.
for (cleaned_tree = conn_trees; *cleaned_tree; ++cleaned_tree) {
while ((conn = ceb64_item_first(*cleaned_tree, hash_node.node,
hash_node.key, struct connection))) {
- if (conn->ctrl->ctrl_close)
+ /*
+ * Make sure we only close our own fds. If the
+ * connection was owned by another thread group,
+ * it should be closed already as all those
+ * threads exited already.
+ */
+ if (conn->ctrl->ctrl_close &&
+ (!(global.tune.options & GTUNE_NO_TG_FD_SHARING) ||
+ ha_thread_info[i].tgid == tgid))
conn->ctrl->ctrl_close(conn);
conn_delete_from_tree(conn, i);
}