]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Change the isc__nm_tcpdns_stoplistening() to be asynchronous event
authorOndřej Surý <ondrej@isc.org>
Fri, 2 Oct 2020 07:28:29 +0000 (09:28 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 8 Oct 2020 05:24:31 +0000 (07:24 +0200)
The isc__nm_tcpdns_stoplistening() would call isc__nmsocket_clearcb()
that would clear the .accept_cb from non-netmgr thread.  Change the
tcpdns_stoplistening to enqueue ievent that would get processed in the
right netmgr thread to avoid locking.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c
lib/isc/netmgr/tcpdns.c

index ceeb5cbb276ad4681017c14009576a046706263a..4d6ef88193084cba23076e3e40f2b36a6aa756d2 100644 (file)
@@ -149,6 +149,7 @@ typedef enum isc__netievent_type {
 
        netievent_tcpdnssend,
        netievent_tcpdnsclose,
+       netievent_tcpdnsstop,
 
        netievent_closecb,
        netievent_shutdown,
@@ -217,6 +218,7 @@ typedef isc__netievent__socket_t isc__netievent_startread_t;
 typedef isc__netievent__socket_t isc__netievent_pauseread_t;
 typedef isc__netievent__socket_t isc__netievent_closecb_t;
 typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t;
+typedef isc__netievent__socket_t isc__netievent_tcpdnsstop_t;
 
 typedef struct isc__netievent__socket_req {
        isc__netievent_type type;
@@ -787,9 +789,10 @@ isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock);
 
 void
 isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0);
-
 void
 isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0);
+void
+isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0);
 
 #define isc__nm_uverr2result(x) \
        isc___nm_uverr2result(x, true, __FILE__, __LINE__)
index 28dc6f22e11f271cfb770d5dd01c1af94efbeacd..6ee8bb72885d7bd7178b5731e7cb2c253263ebca 100644 (file)
@@ -648,6 +648,9 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) {
                case netievent_tcpdnsclose:
                        isc__nm_async_tcpdnsclose(worker, ievent);
                        break;
+               case netievent_tcpdnsstop:
+                       isc__nm_async_tcpdnsstop(worker, ievent);
+                       break;
 
                case netievent_closecb:
                        isc__nm_async_closecb(worker, ievent);
index 5f731ddfee83bfbb76543008e28094d484487414..cb7331d342fbb1c7f6a02be823d1003dd05bdfdc 100644 (file)
@@ -536,12 +536,11 @@ error:
 
 void
 isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
-       isc__netievent_tcpstop_t *ievent = NULL;
-
        REQUIRE(VALID_NMSOCK(sock));
-       REQUIRE(!isc__nm_in_netthread());
+       REQUIRE(sock->type == isc_nm_tcplistener);
 
-       ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstop);
+       isc__netievent_tcpstop_t *ievent =
+               isc__nm_get_ievent(sock->mgr, netievent_tcpstop);
        isc__nmsocket_attach(sock, &ievent->sock);
        isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
                               (isc__netievent_t *)ievent);
index 4e20be080f0fd17e11ae85a44ca900f95eb9e7d4..8060bbfe9a4be56fc702a7ef9f0b7ab0dbf105f6 100644 (file)
@@ -392,18 +392,40 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
 }
 
 void
-isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
+isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) {
+       isc__netievent_tcpstop_t *ievent = (isc__netievent_tcpdnsstop_t *)ev0;
+       isc_nmsocket_t *sock = ievent->sock;
+
+       UNUSED(worker);
+
+       REQUIRE(isc__nm_in_netthread());
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(sock->type == isc_nm_tcpdnslistener);
+       REQUIRE(sock->tid == isc_nm_tid());
 
        atomic_store(&sock->listening, false);
        atomic_store(&sock->closed, true);
+
        isc__nmsocket_clearcb(sock);
 
        if (sock->outer != NULL) {
                isc__nm_tcp_stoplistening(sock->outer);
                isc__nmsocket_detach(&sock->outer);
        }
+
+       isc__nmsocket_detach(&sock);
+}
+
+void
+isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(sock->type == isc_nm_tcpdnslistener);
+
+       isc__netievent_tcpdnsstop_t *ievent =
+               isc__nm_get_ievent(sock->mgr, netievent_tcpdnsstop);
+       isc__nmsocket_attach(sock, &ievent->sock);
+       isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
+                              (isc__netievent_t *)ievent);
 }
 
 void