]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Convert sock->active to non-atomic variable, cleanup rchildren
authorOndřej Surý <ondrej@isc.org>
Tue, 28 Mar 2023 15:03:56 +0000 (17:03 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 30 Mar 2023 14:10:08 +0000 (16:10 +0200)
The last atomic_bool variable sock->active was converted to non-atomic
bool by properly handling the listening socket case where we were
checking parent socket instead of children sockets.

This is no longer necessary as we properly set the .active to false on
the children sockets.

Additionally, cleanup the .rchildren - the atomic variable was used for
mutex+condition to block until all children were listening, but that's
now being handled by a barrier.

Finally, just remove dead .self and .active_child_connections members of
the netmgr socket.

lib/isc/netmgr/http.c
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/streamdns.c
lib/isc/netmgr/tcp.c
lib/isc/netmgr/tlsstream.c
lib/isc/netmgr/udp.c

index 0f7bd8f2d05ac1168cb20986efce1146eae90ee3..51ef77dbe4c70d1b700947b2763e26ee2a251bef 100644 (file)
@@ -2534,7 +2534,6 @@ isc_nm_listenhttp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        sock->fd = (uv_os_sock_t)-1;
 
        isc__nmsocket_barrier_init(sock);
-       atomic_init(&sock->rchildren, sock->nchildren);
 
        sock->listening = true;
        *sockp = sock;
@@ -2712,7 +2711,7 @@ http_close_direct(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
 
        sock->closed = true;
-       atomic_store_release(&sock->active, false);
+       sock->active = false;
        session = sock->h2.session;
 
        if (session != NULL && session->sending == 0 && !session->reading) {
@@ -2840,7 +2839,7 @@ server_call_failed_read_cb(isc_result_t result,
                isc_nmsocket_h2_t *next = ISC_LIST_NEXT(h2data, link);
                ISC_LIST_DEQUEUE(session->sstreams, h2data, link);
                /* Cleanup socket in place */
-               atomic_store_release(&h2data->psock->active, false);
+               h2data->psock->active = false;
                h2data->psock->closed = true;
                isc__nmsocket_detach(&h2data->psock);
 
index fd7e38a20e7abd537b96186c61d4a57e9622905c..d4028090db727ab9d8e4e89bcf928ee589c61302 100644 (file)
@@ -477,6 +477,7 @@ struct isc_nmsocket {
        /*% Unlocked, RO */
        int magic;
        uint32_t tid;
+       isc_refcount_t references;
        isc_nmsocket_type type;
        isc__networker_t *worker;
 
@@ -487,8 +488,6 @@ struct isc_nmsocket {
        isc_nmsocket_t *parent;
        /*% Listener socket this connection was accepted on */
        isc_nmsocket_t *listener;
-       /*% Self socket */
-       isc_nmsocket_t *self;
 
        /*% TLS stuff */
        struct tlsstream {
@@ -580,19 +579,12 @@ struct isc_nmsocket {
        /*% Peer address */
        isc_sockaddr_t peer;
 
-       /* Atomic */
-       /*% Number of running (e.g. listening) child sockets */
-       atomic_uint_fast32_t rchildren;
-
        /*%
         * Socket is active if it's listening, working, etc. If it's
         * closing, then it doesn't make a sense, for example, to
         * push handles or reqs for reuse.
-        *
-        * We might be accessing sock->parent->active from a different
-        * thread, so .active has to be atomic.
         */
-       atomic_bool active;
+       bool active;
        bool destroying;
 
        bool route_sock;
@@ -611,7 +603,6 @@ struct isc_nmsocket {
        bool accepting;
        bool reading;
        bool timedout;
-       isc_refcount_t references;
 
        /*%
         * Established an outgoing connection, as client not server.
@@ -664,8 +655,6 @@ struct isc_nmsocket {
        isc_nm_accept_cb_t accept_cb;
        void *accept_cbarg;
 
-       atomic_int_fast32_t active_child_connections;
-
        bool barriers_initialised;
        bool manual_read_timer;
 #if ISC_NETMGR_TRACE
@@ -767,18 +756,6 @@ isc__nmsocket_active(isc_nmsocket_t *sock);
  * or, for child sockets, 'sock->parent->active'.
  */
 
-bool
-isc__nmsocket_deactivate(isc_nmsocket_t *sock);
-/*%<
- * @brief Deactivate active socket
- *
- * Atomically deactive the socket by setting @p sock->active or, for child
- * sockets, @p sock->parent->active to @c false
- *
- * @param[in] sock - valid nmsocket
- * @return @c false if the socket was already inactive, @c true otherwise
- */
-
 void
 isc__nmsocket_clearcb(isc_nmsocket_t *sock);
 /*%<
index 49123160587ac382bc3dcffa487151a43c2d1d65..36972df7e68d3061bad3d45e25005da66ce2f62d 100644 (file)
@@ -409,24 +409,8 @@ isc_nm_gettimeouts(isc_nm_t *mgr, uint32_t *initial, uint32_t *idle,
 bool
 isc__nmsocket_active(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
-       if (sock->parent != NULL) {
-               return (atomic_load_acquire(&sock->parent->active));
-       }
-
-       return (atomic_load_acquire(&sock->active));
-}
-
-bool
-isc__nmsocket_deactivate(isc_nmsocket_t *sock) {
-       REQUIRE(VALID_NMSOCK(sock));
-
-       if (sock->parent != NULL) {
-               return (atomic_compare_exchange_strong_acq_rel(
-                       &sock->parent->active, &(bool){ true }, false));
-       }
 
-       return (atomic_compare_exchange_strong_acq_rel(&sock->active,
-                                                      &(bool){ true }, false));
+       return (sock->active);
 }
 
 void
@@ -571,7 +555,7 @@ nmsocket_maybe_destroy(isc_nmsocket_t *sock FLARG) {
        }
 
        REQUIRE(!sock->destroying);
-       REQUIRE(!atomic_load_acquire(&sock->active));
+       REQUIRE(!sock->active);
 
        if (!sock->closed) {
                return;
@@ -626,17 +610,12 @@ isc___nmsocket_prep_destroy(isc_nmsocket_t *sock FLARG) {
         * destroying the socket, but we have to wait for all the inflight
         * handles to finish first.
         */
-       atomic_store_release(&sock->active, false);
+       sock->active = false;
 
        /*
-        * If the socket has children, they'll need to be marked inactive
-        * so they can be cleaned up too.
+        * If the socket has children, they have been marked inactive by the
+        * shutdown uv_walk
         */
-       if (sock->children != NULL) {
-               for (size_t i = 0; i < sock->nchildren; i++) {
-                       atomic_store_relaxed(&sock->children[i].active, false);
-               }
-       }
 
        /*
         * If we're here then we already stopped listening; otherwise
@@ -729,6 +708,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc__networker_t *worker,
                .result = ISC_R_UNSET,
                .active_handles = ISC_LIST_INITIALIZER,
                .active_link = ISC_LINK_INITIALIZER,
+               .active = true,
        };
 
        if (iface != NULL) {
@@ -800,10 +780,6 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc__networker_t *worker,
                         "\n",
                         sock, isc_refcount_current(&sock->references));
 
-       atomic_init(&sock->active, true);
-
-       atomic_init(&sock->active_child_connections, 0);
-
 #if HAVE_LIBNGHTTP2
        isc__nm_http_initsocket(sock);
 #endif
@@ -1004,7 +980,7 @@ nmhandle_destroy(isc_nmhandle_t *handle) {
 #if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__)
        nmhandle_free(sock, handle);
 #else
-       if (atomic_load_acquire(&sock->active)) {
+       if (sock->active) {
                ISC_LIST_APPEND(sock->inactive_handles, handle, inactive_link);
        } else {
                nmhandle_free(sock, handle);
@@ -1774,7 +1750,6 @@ static void
 nmsocket_stop_cb(void *arg) {
        isc_nmsocket_t *listener = arg;
 
-       (void)atomic_fetch_sub(&listener->rchildren, 1);
        isc_barrier_wait(&listener->stop_barrier);
 }
 
@@ -1795,7 +1770,6 @@ isc__nmsocket_stop(isc_nmsocket_t *listener) {
        }
 
        nmsocket_stop_cb(listener);
-       INSIST(atomic_load(&listener->rchildren) == 0);
 
        listener->listening = false;
 
index 8aeb1ce639226dbc4842eb3b311a611351e5c101..374d9712de51a76597808ab3ce25c4fd39c77601 100644 (file)
@@ -339,7 +339,7 @@ streamdns_transport_connected(isc_nmhandle_t *handle, isc_result_t result,
        }
 
        isc_nmhandle_attach(handle, &sock->outerhandle);
-       atomic_store_release(&sock->active, true);
+       sock->active = true;
 
        handle->sock->streamdns.sock = sock;
 
@@ -673,7 +673,7 @@ streamdns_accept_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
                           NULL);
        nsock->read_timeout = initial;
        nsock->accepting = true;
-       atomic_store_release(&nsock->active, true);
+       nsock->active = true;
 
        isc__nmsocket_attach(listensock, &nsock->listener);
        isc_nmhandle_attach(handle, &nsock->outerhandle);
@@ -752,12 +752,11 @@ isc_nm_listenstreamdns(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        }
 
        listener->result = result;
-       atomic_store_release(&listener->active, true);
+       listener->active = true;
        listener->listening = true;
        INSIST(listener->outer->streamdns.listener == NULL);
        listener->nchildren = listener->outer->nchildren;
        isc__nmsocket_barrier_init(listener);
-       atomic_init(&listener->rchildren, listener->outer->nchildren);
        isc__nmsocket_attach(listener, &listener->outer->streamdns.listener);
 
        *sockp = listener;
@@ -939,7 +938,7 @@ streamdns_close_direct(isc_nmsocket_t *sock) {
        /* Further cleanup performed in isc__nm_streamdns_cleanup_data() */
        isc_dnsstream_assembler_clear(sock->streamdns.input);
        sock->closed = true;
-       atomic_store_release(&sock->active, false);
+       sock->active = false;
 }
 
 void
index a5bd12b44f608c9417a691e9b7eaf2a0c452ce82..87949791b5092dbd9e2dbdd1a109937729c9e09b 100644 (file)
@@ -300,11 +300,11 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
        (void)isc__nm_socket_min_mtu(sock->fd, sa_family);
        (void)isc__nm_socket_tcp_maxseg(sock->fd, NM_MAXSEG);
 
-       atomic_store_release(&sock->active, true);
+       sock->active = true;
 
        result = tcp_connect_direct(sock, req);
        if (result != ISC_R_SUCCESS) {
-               atomic_store_release(&sock->active, false);
+               sock->active = false;
                isc__nm_tcp_close(sock);
                isc__nm_connectcb(sock, req, result, true);
        }
@@ -436,8 +436,6 @@ done:
        result = isc_uverr2result(r);
 
 done_result:
-       atomic_fetch_add(&sock->parent->rchildren, 1);
-
        if (result != ISC_R_SUCCESS) {
                sock->pquota = NULL;
        }
@@ -505,7 +503,6 @@ isc_nm_listentcp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        sock = isc_mem_get(worker->mctx, sizeof(*sock));
        isc__nmsocket_init(sock, worker, isc_nm_tcplistener, iface, NULL);
 
-       atomic_init(&sock->rchildren, 0);
        sock->nchildren = (workers == ISC_NM_LISTEN_ALL) ? (uint32_t)mgr->nloops
                                                         : workers;
        children_size = sock->nchildren * sizeof(sock->children[0]);
@@ -550,15 +547,15 @@ isc_nm_listentcp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        }
 
        if (result != ISC_R_SUCCESS) {
-               atomic_store_release(&sock->active, false);
+               sock->active = false;
                isc__nm_tcp_stoplistening(sock);
                isc_nmsocket_close(&sock);
 
                return (result);
        }
 
-       atomic_store_release(&sock->active, true);
-       REQUIRE(atomic_load(&sock->rchildren) == sock->nchildren);
+       sock->active = true;
+
        *sockp = sock;
        return (ISC_R_SUCCESS);
 }
@@ -607,6 +604,7 @@ stop_tcp_child_job(void *arg) {
        REQUIRE(sock->type == isc_nm_tcpsocket);
        REQUIRE(!sock->closing);
 
+       sock->active = false;
        sock->closing = true;
 
        /*
@@ -624,8 +622,6 @@ stop_tcp_child_job(void *arg) {
        isc__nmsocket_timer_stop(sock);
        uv_close(&sock->read_timer, NULL);
 
-       (void)atomic_fetch_sub(&sock->parent->rchildren, 1);
-
        REQUIRE(!sock->worker->loop->paused);
        isc_barrier_wait(&sock->parent->stop_barrier);
 }
@@ -634,7 +630,6 @@ static void
 stop_tcp_child(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
 
-       atomic_store_release(&sock->active, false);
        if (sock->tid == 0) {
                stop_tcp_child_job(sock);
        } else {
@@ -653,7 +648,7 @@ isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
        sock->closing = true;
 
        /* Mark the parent socket inactive */
-       atomic_store_release(&sock->active, false);
+       sock->active = false;
 
        /* Stop all the other threads' children */
        for (size_t i = 1; i < sock->nchildren; i++) {
@@ -979,7 +974,7 @@ accept_connection(isc_nmsocket_t *ssock) {
        return (ISC_R_SUCCESS);
 
 failure:
-       atomic_store_release(&csock->active, false);
+       csock->active = false;
 
        failed_accept_cb(csock, result);
 
@@ -1237,9 +1232,10 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
         * If the socket is active, mark it inactive and
         * continue. If it isn't active, stop now.
         */
-       if (!isc__nmsocket_deactivate(sock)) {
+       if (!sock->active) {
                return;
        }
+       sock->active = false;
 
        if (sock->accepting) {
                return;
@@ -1261,11 +1257,15 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
                return;
        }
 
-       /*
-        * Otherwise, we just send the socket to abyss...
-        */
+       /* Destroy the non-listening socket */
        if (sock->parent == NULL) {
                isc__nmsocket_prep_destroy(sock);
+               return;
+       }
+
+       /* Destroy the listening socket if on the same loop */
+       if (sock->tid == sock->parent->tid) {
+               isc__nmsocket_prep_destroy(sock->parent);
        }
 }
 
index 949c27766d8fc1e6695c637811ae37cdb0f5f868..75481e9d8924f81577e3e74cd9cc175fbe323cb3 100644 (file)
@@ -945,7 +945,7 @@ isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        /* wait for listen result */
        isc__nmsocket_attach(tlssock->outer, &tsock);
        tlssock->result = result;
-       atomic_store_release(&tlssock->active, true);
+       tlssock->active = true;
        INSIST(tlssock->outer->tlsstream.tlslistener == NULL);
        isc__nmsocket_attach(tlssock, &tlssock->outer->tlsstream.tlslistener);
        isc__nmsocket_detach(&tsock);
@@ -953,7 +953,6 @@ isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        tlssock->nchildren = tlssock->outer->nchildren;
 
        isc__nmsocket_barrier_init(tlssock);
-       atomic_init(&tlssock->rchildren, tlssock->nchildren);
 
        if (result == ISC_R_SUCCESS) {
                tlssock->listening = true;
@@ -1087,7 +1086,7 @@ tls_close_direct(void *arg) {
 
        /* Further cleanup performed in isc__nm_tls_cleanup_data() */
        sock->closed = true;
-       atomic_store_release(&sock->active, false);
+       sock->active = false;
        sock->tlsstream.state = TLS_CLOSED;
 }
 
@@ -1191,7 +1190,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
        }
        tlssock->peer = isc_nmhandle_peeraddr(handle);
        isc_nmhandle_attach(handle, &tlssock->outerhandle);
-       atomic_store_release(&tlssock->active, true);
+       tlssock->active = true;
 
        if (tlssock->tlsstream.client_sess_cache != NULL) {
                isc_tlsctx_client_session_cache_reuse_sockaddr(
index efa1947aad51d44570ded851d79b02965ec240af..dc985dd1879b4aadac6728635e14dcf2efd86733 100644 (file)
@@ -172,7 +172,6 @@ start_udp_child_job(void *arg) {
 
 done:
        result = isc_uverr2result(r);
-       atomic_fetch_add(&sock->parent->rchildren, 1);
 
        sock->result = result;
 
@@ -232,7 +231,6 @@ isc_nm_listenudp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        sock = isc_mem_get(worker->mctx, sizeof(isc_nmsocket_t));
        isc__nmsocket_init(sock, worker, isc_nm_udplistener, iface, NULL);
 
-       atomic_init(&sock->rchildren, 0);
        sock->nchildren = (workers == ISC_NM_LISTEN_ALL) ? (uint32_t)mgr->nloops
                                                         : workers;
        children_size = sock->nchildren * sizeof(sock->children[0]);
@@ -275,15 +273,15 @@ isc_nm_listenudp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        }
 
        if (result != ISC_R_SUCCESS) {
-               atomic_store_release(&sock->active, false);
+               sock->active = false;
                isc__nm_udp_stoplistening(sock);
                isc_nmsocket_close(&sock);
 
                return (result);
        }
 
-       atomic_store_release(&sock->active, true);
-       INSIST(atomic_load(&sock->rchildren) == sock->nchildren);
+       sock->active = true;
+
        *sockp = sock;
        return (ISC_R_SUCCESS);
 }
@@ -392,11 +390,11 @@ isc_nm_routeconnect(isc_nm_t *mgr, isc_nm_cb_t cb, void *cbarg) {
        req->cbarg = cbarg;
        req->handle = isc__nmhandle_get(sock, NULL, NULL);
 
-       atomic_store_release(&sock->active, true);
+       sock->active = true;
 
        result = route_connect_direct(sock);
        if (result != ISC_R_SUCCESS) {
-               atomic_store_release(&sock->active, false);
+               sock->active = false;
                isc__nm_udp_close(sock);
        }
 
@@ -424,9 +422,9 @@ stop_udp_child_job(void *arg) {
        REQUIRE(sock->tid == isc_tid());
        REQUIRE(sock->parent != NULL);
 
-       isc__nm_udp_close(sock);
+       sock->active = false;
 
-       (void)atomic_fetch_sub(&sock->parent->rchildren, 1);
+       isc__nm_udp_close(sock);
 
        REQUIRE(!sock->worker->loop->paused);
        isc_barrier_wait(&sock->parent->stop_barrier);
@@ -436,7 +434,6 @@ static void
 stop_udp_child(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
 
-       atomic_store_release(&sock->active, false);
        if (sock->tid == 0) {
                stop_udp_child_job(sock);
        } else {
@@ -455,7 +452,7 @@ isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
        sock->closing = true;
 
        /* Mark the parent socket inactive */
-       atomic_store_release(&sock->active, false);
+       sock->active = false;
 
        /* Stop all the other threads' children */
        for (size_t i = 1; i < sock->nchildren; i++) {
@@ -824,12 +821,12 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
        req->local = *local;
        req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface);
 
-       atomic_store_release(&sock->active, true);
+       sock->active = true;
        sock->connecting = true;
 
        result = udp_connect_direct(sock, req);
        if (result != ISC_R_SUCCESS) {
-               atomic_store_release(&sock->active, false);
+               sock->active = false;
                isc__nm_failed_connect_cb(sock, req, result, true);
                isc__nmsocket_detach(&sock);
                return;
@@ -1010,9 +1007,10 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock) {
         * If the socket is active, mark it inactive and
         * continue. If it isn't active, stop now.
         */
-       if (!isc__nmsocket_deactivate(sock)) {
+       if (!sock->active) {
                return;
        }
+       sock->active = false;
 
        /* uv_udp_connect is synchronous, we can't be in connected state */
        REQUIRE(!sock->connecting);
@@ -1031,17 +1029,16 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock) {
                return;
        }
 
-       /*
-        * Ignore the listening sockets
-        */
-       if (sock->parent != NULL) {
+       /* Destroy the non-listening socket */
+       if (sock->parent == NULL) {
+               isc__nmsocket_prep_destroy(sock);
                return;
        }
 
-       /*
-        * Otherwise, we just send the socket to abyss...
-        */
-       isc__nmsocket_prep_destroy(sock);
+       /* Destroy the listening socket if on the same loop */
+       if (sock->tid == sock->parent->tid) {
+               isc__nmsocket_prep_destroy(sock->parent);
+       }
 }
 
 static void