]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: fd: replace usages of fd_remove() with fd_stop_both()
authorWilly Tarreau <w@1wt.eu>
Wed, 26 Aug 2020 09:44:17 +0000 (11:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 26 Aug 2020 16:33:52 +0000 (18:33 +0200)
We used to require fd_remove() to remove an FD from a poller when we
still had the FD cache and it was not possible to directly act on the
pollers. Nowadays we don't need this anymore as the pollers will
automatically unregister disabled FDs. The fd_remove() hack is
particularly problematic because it additionally hides the FD from
the known FD list and could make one think it's closed.

It's used at two places:
  - with the async SSL engine
  - with the listeners (when unbinding from an fd for another process)

Let's just use fd_stop_both() instead, which will propagate down the
stack to do the right thing, without removing the FD from the array
of known ones.

Now when dumping FDs using "show fd" on a process which still knows some
of the other workers' FDs, the FD will properly be listed with a listener
state equal to "ZOM" for "zombie". This guarantees that the FD is still
known and will properly be passed using _getsocks().

src/listener.c
src/ssl_sock.c

index cad0e0cc8474ac215f99cf3cf5aabb3e8dc3a575..6e635e367a1f006975b9af22f323fb23eb930ae2 100644 (file)
@@ -503,13 +503,12 @@ void do_unbind_listener(struct listener *listener, int do_close)
        MT_LIST_DEL(&listener->wait_queue);
 
        if (listener->state >= LI_PAUSED) {
+               listener->state = LI_ASSIGNED;
+               fd_stop_both(listener->fd);
                if (do_close) {
                        fd_delete(listener->fd);
                        listener->fd = -1;
                }
-               else
-                       fd_remove(listener->fd);
-               listener->state = LI_ASSIGNED;
        }
 }
 
index 64208daef5c3f5d2faa718dfec5b874d6c6c0bb3..64c86b11686a423b20ead0bce5da5bd250d8799d 100644 (file)
@@ -700,7 +700,7 @@ void ssl_async_fd_free(int fd)
 
        SSL_get_all_async_fds(ssl, all_fd, &num_all_fds);
        for (i=0 ; i < num_all_fds ; i++)
-               fd_remove(all_fd[i]);
+               fd_stop_both(all_fd[i]);
 
        /* Now we can safely call SSL_free, no more pending job in engines */
        SSL_free(ssl);
@@ -731,7 +731,7 @@ static inline void ssl_async_process_fds(struct ssl_sock_ctx *ctx)
 
        /* We remove unused fds from the fdtab */
        for (i=0 ; i < num_del_fds ; i++)
-               fd_remove(del_fd[i]);
+               fd_stop_both(del_fd[i]);
 
        /* We add new fds to the fdtab */
        for (i=0 ; i < num_add_fds ; i++) {
@@ -6137,12 +6137,12 @@ static void ssl_sock_close(struct connection *conn, void *xprt_ctx) {
                        }
                        /* Else we can remove the fds from the fdtab
                         * and call SSL_free.
-                        * note: we do a fd_remove and not a delete
+                        * note: we do a fd_stop_both and not a delete
                         * because the fd is  owned by the engine.
                         * the engine is responsible to close
                         */
                        for (i=0 ; i < num_all_fds ; i++)
-                               fd_remove(all_fd[i]);
+                               fd_stop_both(all_fd[i]);
                }
 #endif
                SSL_free(ctx->ssl);